Compare commits

...

25 Commits

Author SHA1 Message Date
sairaj mote
c26a778e54 Bug fixes 2023-09-27 22:13:52 +05:30
sairaj mote
b8f0dd296e Bug fix 2023-09-27 19:40:53 +05:30
sairaj mote
cf8dc49082 Bug fixes 2023-09-26 18:42:02 +05:30
sairaj mote
371771080e Update index.html 2023-09-26 15:33:33 +05:30
sairaj mote
b80d588793 Update index.html 2023-09-26 15:22:08 +05:30
Vivek Teega
d8b18a42f8
Merge branch 'ranchimall:master' into testnet 2023-09-25 12:19:28 +05:30
sairaj mote
131ecf5bb4 Update index.html 2023-09-25 03:22:52 +05:30
sairaj mote
e587e3ac98 Update index.html 2023-09-25 03:22:48 +05:30
sairaj mote
b3ce434325 Update index.html 2023-09-25 03:13:12 +05:30
sairaj mote
008231738e Update index.html 2023-09-25 03:13:07 +05:30
sairaj mote
deb352cf03 Update index.html 2023-09-25 03:11:30 +05:30
sairaj mote
36dbf379b1 Update index.html 2023-09-25 03:11:22 +05:30
Vivek Teega
30d4a0e6bb
Merge branch 'ranchimall:master' into testnet 2023-09-25 02:54:11 +05:30
sairaj mote
1ebbf51bb4 Bug fix 2023-09-25 02:51:21 +05:30
sairaj mote
af0ecf4a13 Update index.html 2023-09-25 02:12:36 +05:30
Vivek Teega
01c206388e
Merge branch 'ranchimall:master' into testnet 2023-09-24 21:09:28 +05:30
sairaj mote
8b6f8cac7d Bug fixes 2023-09-24 04:19:19 +05:30
sairaj mote
1b79c0c351 Update index.html 2023-09-23 01:30:17 +05:30
Vivek Teega
faf411aa4b
Merge branch 'ranchimall:master' into testnet 2023-09-23 01:26:44 +05:30
sairaj mote
b8e1fab1c4 Update index.html 2023-09-23 01:26:07 +05:30
Vivek Teega
42ba20a5bf Merge branch 'master' of https://github.com/ranchimall/flowallet into testnet 2023-09-15 23:57:45 +05:30
sairaj mote
f943ea4609 Bug fix 2023-09-14 16:05:57 +05:30
Vivek Teega
851fc56199 Changed to blockbook testnet 2023-09-14 14:39:53 +05:30
Vivek Teega
047d8c5e0a Added blockbook testnet 2023-09-14 14:11:23 +05:30
Vivek Teega
8b19f3ac36 Pushing testnet changes 2023-09-14 13:46:00 +05:30
3 changed files with 680 additions and 634 deletions

View File

@ -16,9 +16,9 @@
<script>
/* Constants for FLO blockchain operations !!Make sure to add this at beginning!! */
const floGlobals = {
blockchain: "FLO",
tokenApiUrl: 'https://ranchimallflo.duckdns.org',
tokenURL: 'https://ranchimallflo.duckdns.org/',
blockchain: "FLO_TEST",
tokenApiUrl: 'https://ranchimallflo-testnet-blockbook.ranchimall.net',
tokenURL: 'https://ranchimallflo-testnet-blockbook.ranchimall.net/',
expirationDays: 60,
}
</script>
@ -43,7 +43,7 @@
compactIDB.initDB("FLOwebWallet", IDBObjects).then(async result => {
render.savedIds();
if (!floGlobals.tokens || !floGlobals.smartContracts) {
fetchJSON(`${floGlobals.tokenApiUrl}/api/v2/tokenSmartContractList`).then(({ tokens, smartContracts }) => {
fetchJson(`${floGlobals.tokenApiUrl}/api/v2/tokenSmartContractList`).then(({ tokens, smartContracts }) => {
floGlobals.scMap = new Map()
floGlobals.tokens = tokens.sort((a, b) => a.localeCompare(b))
floGlobals.smartContracts = smartContracts
@ -54,11 +54,7 @@
routeTo(window.location.hash, { firstLoad: true })
}).catch(e => {
console.error(e)
if (window.location.hash.includes('smartcontracts'))
routeTo('', { firstLoad: true })
else
routeTo(window.location.hash, { firstLoad: true })
getRef('smart_contract_link').classList.add('hidden')
routeTo(window.location.hash, { firstLoad: true, smartContractsUnavailable: true })
}).finally(() => {
loader(false)
})
@ -1182,7 +1178,7 @@
let tempData
async function routeTo(targetPage, options = {}) {
const { firstLoad, hashChange } = options
const { firstLoad, hashChange, smartContractsUnavailable = false } = options
let pageId
let params = {}
let searchParams
@ -1233,6 +1229,10 @@
case 'smartcontracts':
const [subpage] = wildcards
const { type, subtype, scName, scAddress } = params
if (smartContractsUnavailable) {
notify('Smart contracts are currently unavailable, please try again later.', 'error')
return
}
if (subpage) {
switch (subpage) {
case 'create':
@ -1242,34 +1242,13 @@
getRef('smart_contract_creation_form').classList.remove('split-layout')
renderElem(getRef('smart_contract_creation_form'), render.contractCreationForm(type, subtype))
getRef('smart_contract_creation_form').querySelectorAll('[data-flo-address]').forEach(input => {
input.customValidation = floCrypto.validateFloID
input.customValidation = (value) => {
return {
isValid: floCrypto.validateAddr(value),
errorText: `Invalid FLO address.<br> It usually starts with "F".`
}
}
})
switch (type) {
case 'one-time-event':
switch (subtype) {
case 'time-trigger':
const payeeAddressObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
if (mutation.addedNodes.length) {
}
if (mutation.removedNodes.length) {
}
}
});
});
payeeAddressObserver.observe(document.getElementById('payee_container'), { childList: true });
break;
case 'external-trigger':
break;
}
break;
case 'continuous-event':
break;
}
showChildElement('smartcontracts', 1, { entry: slideInLeft, exit: slideOutLeft })
break;
case 'deposit': {
@ -1279,7 +1258,7 @@
if (scName && scAddress)
selectedSmartContract = getScDetails(scName, scAddress)
const { price, contractName, contractAddress, acceptingToken, sellingToken, tokenIdentification, contractSubType } = selectedSmartContract
history.replaceState(null, null, `#/smartcontracts/deposit?scName=${contractName}&scAddress=${contractAddress}`)
history.replaceState(null, null, `#/smartcontracts/${subpage}?scName=${contractName}&scAddress=${contractAddress}`)
const defaultExpiration = new Date(new Date().getTime() + (floGlobals.expirationDays * 24 * 60 * 60 * 1000))
.toISOString().slice(0, -8);
renderElem(getRef('smart_contract_deposit_form'), html`
@ -1334,7 +1313,7 @@
if (scName && scAddress)
selectedSmartContract = getScDetails(scName, scAddress)
const { price, contractName, contractAddress, acceptingToken, sellingToken, tokenIdentification, userChoices, contractSubType } = selectedSmartContract
history.replaceState(null, null, `#/smartcontracts/participate?scName=${contractName}&scAddress=${contractAddress}`)
history.replaceState(null, null, `#/smartcontracts/${subpage}?scName=${contractName}&scAddress=${contractAddress}`)
renderElem(getRef('smart_contract_participate_form'), html`
<div class="grid gap-0-5">
<span class="label">Select smart contract</span>
@ -1396,7 +1375,7 @@
if (scName && scAddress)
selectedSmartContract = getScDetails(scName, scAddress)
const { contractName, contractAddress, oracle_address, price, acceptingToken } = selectedSmartContract
history.replaceState(null, null, `#/smartcontracts/participate?scName=${contractName}&scAddress=${contractAddress}`)
history.replaceState(null, null, `#/smartcontracts/${subpage}?scName=${contractName}&scAddress=${contractAddress}`)
renderElem(getRef('smart_contract_update_form'), html`
<div class="grid gap-0-5">
<span class="label">Oracle FLO Address</span>
@ -1448,7 +1427,7 @@
if (scName && scAddress)
selectedSmartContract = getScDetails(scName, scAddress)
const { contractName, contractAddress, price, tokenIdentification, userChoices } = selectedSmartContract
history.replaceState(null, null, `#/smartcontracts/trigger?scName=${contractName}&scAddress=${contractAddress}`)
history.replaceState(null, null, `#/smartcontracts/${subpage}?scName=${contractName}&scAddress=${contractAddress}`)
renderElem(getRef('smart_contract_trigger_form'), html`
<div class="grid gap-0-5">
<span class="label">Select smart contract</span>
@ -1468,7 +1447,7 @@
</div>
</fieldset>
<div class="grid gap-0-5">
<span class="label">Contract address FLO private key</span>
<span class="label">Committee address FLO private key</span>
<sm-input id="trigger_private_key" class="password-field" type="password" error-text="Invalid private key" data-private-key="" required="">
<label slot="right" class="interact">
<input type="checkbox" class="hidden" readonly="" onchange="togglePrivateKeyVisibility(this)">
@ -1501,12 +1480,40 @@
}
break
}
let previousActiveElement = getRef('main_navbar').querySelector('.nav-item--active')
const currentActiveElement = document.querySelector(`.nav-item[href="#/${pageId}"]`)
if (document.startViewTransition) {
document.startViewTransition(() => {
if (previousActiveElement) {
previousActiveElement.classList.remove('nav-item--active');
previousActiveElement.querySelector('.nav-item__indicator')?.remove()
}
if (currentActiveElement) {
if (getRef('main_navbar').classList.contains('hidden')) {
getRef('main_navbar').classList.remove('hide-away')
getRef('main_navbar').classList.remove('hidden')
}
getRef('main_header').classList.remove('hidden')
currentActiveElement.classList.add('nav-item--active')
currentActiveElement.append(createElement('div', { className: 'nav-item__indicator' }));
} else {
if (!getRef('main_navbar').classList.contains('hidden')) {
getRef('main_navbar').classList.add('hide-away')
getRef('main_navbar').classList.add('hidden')
getRef('main_header').classList.add('hidden')
}
}
if (pagesData.lastPage !== pageId) {
document.querySelectorAll('.page').forEach(page => page.classList.add('hidden'))
getRef(pageId).classList.remove('hidden')
pagesData.lastPage = pageId
}
})
} else {
const animOptions = {
duration: 100,
fill: 'forwards',
}
let previousActiveElement = getRef('main_navbar').querySelector('.nav-item--active')
const currentActiveElement = document.querySelector(`.nav-item[href="#/${pageId}"]`)
if (currentActiveElement) {
if (getRef('main_navbar').classList.contains('hidden')) {
getRef('main_navbar').classList.remove('hide-away')
@ -1596,8 +1603,19 @@
getRef(pageId).animate([{ opacity: 0 }, { opacity: 1 }], { duration: 300, fill: 'forwards', easing: 'ease' })
pagesData.lastPage = pageId
}
document.querySelectorAll('sm-input[data-flo-address]').forEach(input => input.customValidation = floCrypto.validateFloID)
document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex)
}
document.querySelectorAll('sm-input[data-flo-address]').forEach(input => input.customValidation = (value) => {
return {
isValid: floCrypto.validateAddr(value),
errorText: `Invalid FLO address.<br> It usually starts with "F"`
}
})
document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = (value) => {
return {
isValid: floCrypto.getPubKeyHex(value),
errorText: `Invalid private key.<br> It's a long string of random characters usually starting with 'R'.`
}
})
}
const indicatorObserver = new IntersectionObserver(entries => {
@ -1718,7 +1736,7 @@
handleMobileChange(mobileQuery)
// fetch data and return json
async function fetchJSON(url, options = {}) {
async function fetchJson(url, options = {}) {
const response = await fetch(url, options)
const json = await response.json()
if (response.ok) {
@ -1984,7 +2002,7 @@
availableSmartContractOptions(smartContracts = [], selected) {
return smartContracts
.map(({ contractName, contractAddress }) => html`
<sm-option class="breakable" value=${`${contractName}_${contractAddress}`} ?selected=${`${contractName}_${contractAddress}` === `${selected}`}>${`${replaceDash(contractName)} (${contractAddress})`}</sm-option>
<sm-option class="breakable" value=${`${contractName}_${contractAddress}`} selected=${`${contractName}_${contractAddress}` === `${selected}`}>${`${replaceDash(contractName)} (${contractAddress})`}</sm-option>
`)
},
contractCreationForm(type, subtype) {
@ -2100,7 +2118,7 @@
</div>
<div class="grid gap-0-5">
<span class="label">Price (1 deposit token = ? participation token)</span>
<sm-input id="contract_initial_price" type="number" required> </sm-input>
<sm-input id="contract_initial_price" type="number" step="0.00000001" min="0.00000001" required> </sm-input>
</div>
`}
<div class="grid gap-0-5">
@ -2314,7 +2332,7 @@
const senderFloAddr = floCrypto.getFloID(senderPrivateKey)
Promise.all([
floWebWallet.getBalance(senderFloAddr),
fetchJSON(`${floGlobals.tokenApiUrl}/api/v2/floAddressBalance/${senderFloAddr}`)
fetchJson(`${floGlobals.tokenApiUrl}/api/v2/floAddressBalance/${senderFloAddr}`)
]).then(([retrievedBal, { floAddressBalances }]) => {
renderBalance({ balance: parseFloat(retrievedBal), address: senderFloAddr })
let ownedTokens = []
@ -2531,7 +2549,7 @@
getRef('flo_balance').innerHTML = `<sm-spinner></sm-spinner>`;
const [floBalance, tokenBalances] = await Promise.all([
floWebWallet.getBalance(queriedFloId),
fetchJSON(`${floGlobals.tokenApiUrl}/api/v2/floAddressBalance/${queriedFloId}`).then(({ floAddressBalances }) => floAddressBalances)
fetchJson(`${floGlobals.tokenApiUrl}/api/v2/floAddressBalance/${queriedFloId}`).then(({ floAddressBalances }) => floAddressBalances)
])
let ownedTokens = []
for (const token in tokenBalances) {
@ -2817,7 +2835,7 @@
name = floGlobals.smartContracts[0].contractName
address = floGlobals.smartContracts[0].contractAddress
}
fetchJSON(`${floGlobals.tokenApiUrl}/api/v2/smartContractInfo?contractName=${name}&contractAddress=${address}`)
fetchJson(`${floGlobals.tokenApiUrl}/api/v2/smartContractInfo?contractName=${name}&contractAddress=${address}`)
.then(info => {
console.log(info)
const {
@ -2878,17 +2896,23 @@
}
function filterSmartContracts(options) {
const { type, subType, dynamic = false } = options || {}
let filteredSmartContracts = (floGlobals.smartContracts || [])
.filter(sc => sc.status === 'active')
const { type, subType, dynamic = false } = options || {};
let filteredSmartContracts = floGlobals.smartContracts || [];
if (type) {
filteredSmartContracts = filteredSmartContracts.filter(sc => sc.contractType === type)
if (type === 'continuos-event' && dynamic)
filteredSmartContracts = filteredSmartContracts.filter(sc => sc.oracle_address)
filteredSmartContracts = filteredSmartContracts.filter(sc => {
if (subType && subType === 'external-trigger') {
return sc.status === 'expired'; // only inactive contracts can be triggered externally
} else if (type === 'continuos-event' && dynamic) {
return sc.status === 'active' && sc.contractType === type && sc.oracle_address;
} else {
return sc.status === 'active' && sc.contractType === type;
}
if (subType)
filteredSmartContracts = filteredSmartContracts.filter(sc => sc.contractSubType === subType)
return filteredSmartContracts
});
}
if (subType) {
filteredSmartContracts = filteredSmartContracts.filter(sc => sc.contractSubType === subType);
}
return filteredSmartContracts;
}
function handleSmartContractSelection(actionType) {
@ -3018,6 +3042,7 @@
const [contractName, contractAddress] = (selectedSmartContract).split('_')
const oraclePrivateKey = document.getElementById('oracle_private_key').value.trim()
const oracleAddress = document.getElementById('oracle_address').value
const { acceptingToken } = getScDetails(contractName, contractAddress)
if (!floCrypto.verifyPrivKey(oraclePrivateKey, oracleAddress)) {
return notify(`Private key doesn't match with Oracle address`, 'error')
}
@ -3025,7 +3050,7 @@
const floData = ` {"price-update":{"contract-name": "${contractName}", "contract-address": "${contractAddress}", "price": ${updatedPrice}}} `
console.log(floData)
getConfirmation('Update price', {
message: `Are you sure you want to update the price of ${contractName} to ${updatedPrice} FLO?`,
message: `Are you sure you want to update the price of ${contractName} to ${updatedPrice} ${acceptingToken}?`,
confirmText: 'Update',
cancelText: 'Cancel'
}).then((res) => {
@ -3054,9 +3079,9 @@
const triggerOutcome = getRef('smart_contract_trigger_form').querySelector('input[name="outcome"]:checked').value
const floData = `${contractName}@ triggerCondition:"${triggerOutcome}"`
console.log(floData)
if (contractAddress !== triggerAddress) {
return notify(`Private key doesn't match with contract trigger address`, 'error')
}
// if (contractAddress !== triggerAddress) {
// return notify(`Private key doesn't match with contract trigger address`, 'error')
// }
getConfirmation('Trigger contract', {
message: `Triggering ${contractName} with outcome: ${triggerOutcome}`,
confirmText: 'Trigger',
@ -3064,7 +3089,7 @@
}).then((res) => {
if (!res) return
buttonLoader('trigger_contract_button', true)
floBlockchainAPI.writeData(contractAddress, floData, triggerPrivateKey, contractAddress).then((txid) => {
floBlockchainAPI.writeData(triggerAddress, floData, triggerPrivateKey, contractAddress).then((txid) => {
showTransactionResult(true, txid, {
title: 'Contract trigger initiated',
})
@ -3113,13 +3138,22 @@
return notify(`Contract expiration datetime cannot be in the past`, 'error')
}
const contractParticipationAmount = parseFloat(document.getElementById('contract_participation_amount').value.trim()) || 0;
const contractMinSubAmount = parseFloat(document.getElementById('contract_min_sub_amount').value.trim()) || 0;
const contractMaxSubAmount = parseFloat(document.getElementById('contract_max_sub_amount').value.trim()) || 0;
if (contractMinSubAmount > contractMaxSubAmount) {
const contractMinSubAmount = parseFloat(document.getElementById('contract_min_sub_amount').value.trim());
const contractMaxSubAmount = parseFloat(document.getElementById('contract_max_sub_amount').value.trim());
if (contractMinSubAmount && contractMaxSubAmount && contractMinSubAmount > contractMaxSubAmount) {
return notify(`Contract minimum subscription amount cannot be greater than maximum subscription amount`, 'error')
}
const contractConditions = {}
if (contractExpiration)
contractConditions.expiryTime = new Date(contractExpiration).toString()
if (contractParticipationAmount)
contractConditions.contractamount = contractParticipationAmount
if (contractMinSubAmount)
contractConditions.minimumsubscriptionamount = contractMinSubAmount
if (contractMaxSubAmount)
contractConditions.maximumsubscriptionamount = contractMaxSubAmount
switch (subtype) {
case 'time-trigger':
case 'time-trigger': {
const payeeAddressesShare = {}
document.querySelectorAll('.payee-address-wrapper').forEach((payeeAddressWrapper) => {
const payeeAddress = payeeAddressWrapper.querySelector('.payee-address').value.trim()
@ -3153,27 +3187,35 @@
return notify(`Total share cannot be greater than 100`, 'error')
}
const payeeAddressesShareString = Object.entries(payeeAddressesShare).map(([payeeAddress, payeeShare]) => `${payeeAddress}:${payeeShare}`).join(':')
console.log(payeeAddressesShareString)
floData = `Create a smart contract of the name ${contractName}@ of the type one-time-event* using asset ${contractAsset}# at the FLO address ${creatorAddress}$ with contract-conditions: (1) expiryTime= ${new Date(contractExpiration).toString()} (2) payeeAddress= ${payeeAddressesShareString} ${contractParticipationAmount ? `(3) contractamount = ${contractParticipationAmount}` : ''} ${contractMinSubAmount ? `(4) minimumsubscriptionamount = ${contractMinSubAmount}` : ''} ${contractMaxSubAmount ? `(5) maximumsubscriptionamount = ${contractMaxSubAmount}` : ''} end-contract-conditions`
if (payeeAddressesShareString)
contractConditions.payeeAddress = payeeAddressesShareString
const contractConditionsString = Object.entries(contractConditions).map(([key, value], index) => `(${index + 1}) ${key}= ${value}`).join(' ')
floData = `Create a smart contract of the name ${contractName}@ of the type one-time-event* using asset ${contractAsset}# at the FLO address ${creatorAddress}$ with contract-conditions: ${contractConditionsString} end-contract-conditions`
if (floData.length > 1040) return notify(`Too many payee addresses! remove some and try again`, 'error')
confirmationMessage = `Name: ${contractName} \nType: One-time event \nSubtype: Time trigger \nAsset: ${contractAsset} \nExpiration: ${new Date(contractExpiration).toString()} \nPayee addresses: ${Object.entries(payeeAddressesShare).reduce((str, [address, share]) => `${address}: ${share}%`, '')} \nParticipation amount: ${contractParticipationAmount} ${contractAsset} \nMin subscription amount: ${contractMinSubAmount} ${contractAsset} \nMax subscription amount: ${contractMaxSubAmount} ${contractAsset}`
break;
case 'external-trigger':
// add confirmation message with contract details only if they are defined
confirmationMessage = `Name: ${contractName} \nType: One time event \nSubtype: Time trigger \nAsset: ${contractAsset} \nExpiration: ${new Date(contractExpiration).toString()} \nPayee addresses: ${payeeAddressesShareString} ${contractParticipationAmount ? `\nParticipation amount: ${contractParticipationAmount} ${contractAsset}` : ''} ${contractMinSubAmount ? `\nMinimum subscription amount: ${contractMinSubAmount} ${contractAsset}` : ''} ${contractMaxSubAmount ? `\nMaximum subscription amount: ${contractMaxSubAmount} ${contractAsset}` : ''}`
} break;
case 'external-trigger': {
const userChoices = new Set()
document.querySelectorAll('.user-choice').forEach((userChoice) => {
const userChoiceValue = userChoice.value.trim()
if (userChoiceValue !== '')
userChoices.add(userChoiceValue)
})
floData = `Create a smart contract of the name ${contractName}@ of the type one-time-event* using asset ${contractAsset}# at the FLO address ${creatorAddress}$ with contract-conditions:(1) expiryTime= ${new Date(contractExpiration).toString()} (2) userchoices= ${[...userChoices].join(' | ')} ${contractParticipationAmount ? `(3) contractamount = ${contractParticipationAmount}` : ''} ${contractMinSubAmount ? `(4) minimumsubscriptionamount = ${contractMinSubAmount}` : ''} ${contractMaxSubAmount ? `(5) maximumsubscriptionamount = ${contractMaxSubAmount}` : ''} end-contract-conditions`
if (userChoices.size)
contractConditions.userchoices = [...userChoices].join(' | ')
const contractConditionsString = Object.entries(contractConditions).map(([key, value], index) => `(${index + 1}) ${key}= ${value}`).join(' ')
floData = `Create a smart contract of the name ${contractName}@ of the type one-time-event* using asset ${contractAsset}# at the FLO address ${creatorAddress}$ with contract-conditions:${contractConditionsString} end-contract-conditions`
if (floData.length > 1040) return notify(`Too many participant choices! remove some and try again`, 'error')
confirmationMessage = `Name: ${contractName} \nType: One-time event \nSubtype: External trigger \nAsset: ${contractAsset} \nExpiration: ${new Date(contractExpiration).toString()} \nParticipant choices: ${[...userChoices].join(' | ')} \nParticipation amount: ${contractParticipationAmount} ${contractAsset} \nMin subscription amount: ${contractMinSubAmount} ${contractAsset} \nMax subscription amount: ${contractMaxSubAmount} ${contractAsset}`
break;
// add confirmation message with contract details only if they are defined
confirmationMessage = `Name: ${contractName} \nType: One time event \nSubtype: External trigger \nAsset: ${contractAsset} \nExpiration: ${new Date(contractExpiration).toString()} \nUser choices: ${[...userChoices].join(' | ')} ${contractParticipationAmount ? `\nParticipation amount: ${contractParticipationAmount} ${contractAsset}` : ''} ${contractMinSubAmount ? `\nMinimum subscription amount: ${contractMinSubAmount} ${contractAsset}` : ''} ${contractMaxSubAmount ? `\nMaximum subscription amount: ${contractMaxSubAmount} ${contractAsset}` : ''}`
} break;
}
break;
case 'continuous-event':
switch (subtype) {
case 'tokenswap':
case 'tokenswap': {
const priceType = document.querySelector('input[name="price-type"]:checked').value
const participationToken = document.getElementById('contract_input_token').value
const depositToken = document.getElementById('contract_output_token').value
@ -3184,7 +3226,7 @@
oracleAddress = document.getElementById('contract_oracle_address').value.trim()
floData = `Create Smart Contract with the name ${contractName}@ of the type continuous-event* at the address ${creatorAddress}$ with contract-conditions : (1) subtype = tokenswap (2) accepting_token = ${participationToken}# (3) selling_token = ${depositToken}# (4) price = '${initialPrice}' (5) priceType = ${priceType} ${oracleAddress ? `(6) oracle_address = ${oracleAddress}` : ''} end-contract-conditions`
confirmationMessage = `Name: ${contractName} \nType: Continuous event \nSubtype: Token swap \nDeposit token: ${depositToken} \nParticipation token: ${participationToken} \nInitial price: ${initialPrice} ${participationToken} per ${depositToken} \nPrice type: ${priceType} ${oracleAddress ? `\nOracle address: ${oracleAddress}` : ''}`
break;
} break;
}
break;
}
@ -3226,7 +3268,12 @@
document.getElementById('payee_container').querySelectorAll('.payee-share').forEach((input) => {
input.value = parseFloat((100 / document.getElementById('payee_container').querySelectorAll('.payee-share').length).toFixed(2))
})
document.getElementById('payee_container').lastElementChild.querySelector('.payee-address').customValidation = floCrypto.validateFloID
document.getElementById('payee_container').lastElementChild.querySelector('.payee-address').customValidation = (value) => {
return {
isValid: floCrypto.validateAddr(value),
errorText: `Invalid FLO address.<br> It usually starts with "F".`
}
}
}
function removePayee(e) {
e.target.closest('li').remove()
@ -3270,7 +3317,6 @@
function replaceDash(str) {
return str.replace(/-/g, ' ')
}
</script>
</body>

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,7 @@
blockchain: floGlobals.blockchain,
apiURL: {
FLO: ['https://blockbook.ranchimall.net/'],
FLO_TEST: []
FLO_TEST: ['https://blockbook-testnet.ranchimall.net/']
},
sendAmt: 0.0003,
fee: 0.0002,