@@ -147,7 +176,7 @@ let contactsList = await setupContactsList(
contactAccountID,
)
- if (!contactData.outgoing) {
+ if (isEmpty(contactData.outgoing)) {
// Finish Pairing
let contactName = contactData?.info?.name || 'Contact'
await appDialogs.addContact.render(
@@ -205,109 +234,23 @@ let contactsList = await setupContactsList(
if (
getTarget(event, 'add_contact')
) {
- await getUserInfo()
-
- let selectedWallet = wallets?.[appState.selectedWallet]
- let accountIndex = selectedWallet
- ?.accountIndex || 0
+ let generateNewContact = await putContact({})
- let shareAccount
- let newContact
- let newAccount
+ appState.contacts = [
+ ...appState.contacts,
+ generateNewContact.newContact,
+ ]
- if (appState.phrase) {
- console.log(
- 'share qr current wallet',
- accountIndex,
- selectedWallet?.xkeyId,
- selectedWallet,
- )
-
- accountIndex += 1
-
- if (selectedWallet) {
- let upWallet = await store.wallets.setItem(
- appState.selectedWallet,
- {
- ...selectedWallet,
- accountIndex,
- updatedAt: (new Date()).toISOString(),
- }
- )
- wallets[appState.selectedWallet] = upWallet
- }
-
- shareAccount = await deriveWalletData(
- appState.phrase,
- accountIndex,
- )
-
- console.log('main.js contact account', shareAccount)
-
- let created = (new Date()).toISOString()
- let usage = [0,0]
-
- newAccount = await store.accounts.setItem(
- shareAccount.xkeyId,
- {
- createdAt: created,
- updatedAt: (new Date()).toISOString(),
- accountIndex,
- usage,
- walletId: shareAccount.id,
- xkeyId: shareAccount.xkeyId,
- addressKeyId: shareAccount.addressKeyId,
- address: shareAccount.address,
- }
- )
- let { createdAt, updatedAt, ...contactAcct } = newAccount
-
- let { addresses, finalAddressIndex } = await batchGenAcctAddrs(
- wallet,
- newAccount,
- ) ?? {}
-
- console.log(
- 'share qr derived wallet',
- accountIndex,
- finalAddressIndex,
- addresses,
- shareAccount,
- )
-
- newContact = await appTools.storedData.encryptItem(
- store.contacts,
- shareAccount.xkeyId,
- {
- createdAt,
- updatedAt,
- incoming: {
- [`${contactAcct.walletId}/${contactAcct.xkeyId}`]: {
- ...contactAcct,
- }
- }
- },
- false,
- )
-
- appState.contacts.push(newContact)
-
- await contactsList.render({
- userInfo,
- contacts: appState.contacts,
- })
-
- console.log(
- 'share qr new contact',
- newContact,
- )
- }
+ await contactsList.render({
+ userInfo,
+ contacts: appState.contacts,
+ })
await appDialogs.addContact.render(
{
name: 'Add a New Contact',
- wallet: shareAccount,
- contact: newContact,
+ wallet: generateNewContact.shareAccount,
+ contact: generateNewContact.newContact,
userInfo,
},
'afterend',
@@ -318,6 +261,8 @@ let contactsList = await setupContactsList(
},
}
)
+appComponents.contactsList = contactsList
+
let transactionsList = await setupTransactionsList(mainAppGrid, {
events: {
handleClick: state => async event => {
@@ -337,152 +282,13 @@ let transactionsList = await setupTransactionsList(mainAppGrid, {
},
})
-async function getUserInfo() {
- let ks = wallets?.[appState.selectedWallet]?.keystore
-
- if (
- appState.encryptionPassword && appState.selectedAlias && ks
- ) {
- appTools.storedData = storedData(
- appState.encryptionPassword,
- ks,
- )
-
- await appTools.storedData?.decryptItem(
- store.aliases,
- appState.selectedAlias,
- )
- .then(async $alias => {
- let { $wallets, ...$userInfo } = await loadWalletsForAlias(
- $alias
- )
- wallets = $wallets
- console.log(
- 'getUserInfo $alias',
- {
- $alias,
- $wallets,
- $userInfo,
- }
- )
-
- Object.entries(($userInfo?.info || {}))
- .forEach(
- ([k,v]) => userInfo[k] = v
- )
- })
- .catch(err => {
- showErrorDialog({
- title: 'Unable to decrypt seed phrase',
- msg: err,
- showActBtn: false,
- confirmAction: appDialogs.confirmAction,
- })
- })
- }
-}
-
-async function handlePasswordToggle(event) {
- let {
- // @ts-ignore
- name: fieldName, form,
- } = event?.target
-
- if (
- fieldName === 'show_pass'
- ) {
- event.stopPropagation()
- event.preventDefault()
-
- let { pass, show_pass, } = form
-
- if (show_pass?.checked) {
- pass.type = 'text'
- } else {
- pass.type = 'password'
- }
- }
-}
-
-function getTarget(event, selector) {
- let {
- // @ts-ignore
- id,
- // @ts-ignore
- parentElement,
- // @ts-ignore
- parentNode,
- } = event?.target
-
- let target
-
- if (id === selector) {
- target = event?.target
- }
-
- if (parentElement?.id === selector) {
- target = parentElement
- }
-
- if (parentNode?.id === selector) {
- target = parentNode
- }
-
- return target
-}
-
-async function showNotification({
- type = '',
- title = '',
- msg = '',
- sticky = false,
-}) {
- console.log('notification', {type, title, msg, sticky})
-}
-
-async function showQrCode(state = {}) {
- let initState = {
- name: 'Share to receive funds',
- submitTxt: `Edit Amount or Contact`,
- submitAlt: `Change the currently selected contact`,
- footer: state => html`
-
- `,
- amount: 0,
- wallet,
- contacts: appState.contacts,
- ...state,
- }
-
- let showRequestQRRender = await appDialogs.requestQr.render(
- initState,
- 'afterend',
- )
-
- let showRequestQR = await appDialogs.requestQr.showModal()
-
- return showRequestQRRender
-}
-
async function main() {
appState.encryptionPassword = window.atob(
sessionStorage.encryptionPassword || ''
)
- appState.selectedWallet = localStorage?.selectedWallet || ''
appState.selectedAlias = localStorage?.selectedAlias || ''
appState.selectedAccount = localStorage?.selectedAccount || ''
-
- wallets = await getStoredItems(store.wallets)
+ appState.selectedWallet = localStorage?.selectedWallet || ''
console.log('main wallets', wallets)
@@ -493,7 +299,7 @@ async function main() {
accounts = await findInStore(
store.accounts,
{
- walletId: appState.selectedWallet,
+ walletId: localStorage.selectedWallet,
accountIndex: 0,
}
)
@@ -510,19 +316,21 @@ async function main() {
)
appDialogs.confirmAction = await confirmActionRig({
- mainApp, setupDialog,
- appDialogs, appState, appTools,
+ mainApp, appDialogs, appState, appTools,
+ setupDialog,
})
appDialogs.walletEncrypt = await walletEncryptRig({
- setupDialog, appDialogs, appState, appTools, mainApp,
+ appDialogs, appState, appTools, mainApp,
wallet, wallets, bodyNav, dashBalance,
+ setupDialog,
})
appDialogs.walletDecrypt = await walletDecryptRig({
- setupDialog, appDialogs, appState, mainApp, importFromJson,
- wallets, decryptKeystore, getUserInfo, store, deriveWalletData,
- showErrorDialog,
+ appDialogs, appState, appTools, mainApp,
+ wallets, store,
+ importFromJson, decryptKeystore, getUserInfo,
+ deriveWalletData, showErrorDialog, setupDialog,
})
appDialogs.walletBackup = await walletBackupRig({
@@ -608,13 +416,14 @@ async function main() {
svgSprite.render()
- let ks = wallets?.[appState.selectedWallet]
- ?.keystore
+ appState.keystore = getStoredWallet()?.keystore
+
+ let ks = appState.keystore
let ks_phrase = ks?.crypto?.ciphertext || ''
let ks_iv = ks?.crypto?.cipherparams?.iv || ''
let ks_salt = ks?.crypto?.kdfparams?.salt || ''
- if (appState.encryptionPassword && ks) {
+ if (appState.encryptionPassword && appState.keystore) {
try {
appState.phrase = await decryptKeystore(
appState.encryptionPassword,
@@ -691,9 +500,6 @@ async function main() {
if (fde.intent === 'receive') {
let receiveWallet
- let selectedWallet = wallets?.[appState.selectedWallet]
-
- // console.log('selectedWallet', wallet, selectedWallet)
if (wallet?.xkeyId) {
let aw = await getAccountWallet(
@@ -716,7 +522,9 @@ async function main() {
// }
// )
- showQrCode()
+ showQrCode({
+ wallet,
+ })
// let showRequestQR = await appDialogs.requestQr.showModal()
}
@@ -764,8 +572,6 @@ async function main() {
})
mainFtr.render()
- wallets = wallets || await getStoredItems(store.wallets)
-
await getUserInfo()
// contactsList.render({
@@ -776,6 +582,9 @@ async function main() {
appState.transactions = await loadStoreObject(
store.transactions,
)
+ appState.integrations = await loadStoreObject(
+ store.integrations,
+ )
// console.log('appState.transactions', appState.transactions)
@@ -811,19 +620,67 @@ async function main() {
walletFunds,
})
})
+
import('./components/crowdnode-card.js')
.then(async ({ CrowdNodeCard }) => {
+ let cnAPI = await appTools.storedData?.decryptItem?.(
+ store.integrations,
+ 'crowdnode',
+ )
+ let cnEncAPI = await store.integrations.getItem('crowdnode')
+ // let minimumNeededFunds = 1.1
+ let minimumNeededFunds = 0.01
+ let cnShareAccount
+ let cnAddr
+
+ let cnContactExists = await findContactByAlias(
+ 'crowdnode'
+ )
+
+ if (cnContactExists) {
+ let contactAccountIndex = Object.values(
+ cnContactExists.incoming || {}
+ )?.[0]?.accountIndex
+
+ cnShareAccount = await deriveWalletData(
+ appState.phrase,
+ contactAccountIndex,
+ )
+
+ cnAddr = await store.addresses.getItem(
+ cnShareAccount.address
+ )
+
+ console.log('use existing crowdnode contact', {
+ cnContactExists,
+ cnShareAccount,
+ cnAddr,
+ })
+ }
+ // TODO: find Contact by Hot Wallet Address in Transactions
+
+ console.warn(
+ 'CN Funds',
+ {
+ walletBalance: walletFunds.balance,
+ crowdnodeAddrBalance: cnAddr?.insight?.balance || 0,
+ minimumNeededFunds,
+ }
+ )
+
+ console.log(
+ `CrowdNodeCard`,
+ { cnAPI, cnEncAPI },
+ )
+
let cfg = {
state: {
- // name: '',
},
events: {
submit: async event => {
event.preventDefault()
event.stopPropagation()
- // this.elements.form?.removeEventListener('submit', this.events.submit)
-
let fde = formDataEntries(event)
console.log(
@@ -831,6 +688,15 @@ async function main() {
{event, fde},
)
+ console.warn(
+ 'CN Funds',
+ {
+ walletBalance: walletFunds.balance,
+ crowdnodeAddrBalance: cnAddr?.insight?.balance || 0,
+ minimumNeededFunds,
+ }
+ )
+
if (fde.intent === 'signup') {
let confAct = await appDialogs.confirmAction.render({
name: 'Signup for Crowdnode',
@@ -870,28 +736,118 @@ async function main() {
let cbConfAct = await appDialogs.confirmAction.render(state)
+ cnCard.api.value = {
+ ...(cnAPI || {}),
+ acceptedToS: true,
+ balance: 0,
+ }
+
+ if (!cnContactExists) {
+ let generatedContact = await putContact({
+ uri: CROWDNODE.network.main.hotwallet,
+ alias: 'crowdnode',
+ info: {
+ name: 'CrowdNode',
+ preferred_username: 'crowdnode',
+ picture: '/public/icons/CrowdNode.svg',
+ },
+ })
+
+ appState.contacts = [
+ ...appState.contacts,
+ generatedContact.newContact
+ ]
+ cnShareAccount = generatedContact.shareAccount
+ } else {
+ let contactAccountIndex = Object.values(cnContactExists.incoming || {})?.[0]?.accountIndex
+
+ cnShareAccount = await deriveWalletData(
+ appState.phrase,
+ contactAccountIndex,
+ )
+
+ console.log('use existing crowdnode contact', cnContactExists, cnShareAccount)
+ }
+
+ await contactsList.render({
+ userInfo,
+ contacts: appState.contacts,
+ })
+
+ appTools.storedData?.encryptItem?.(
+ store.integrations,
+ 'crowdnode',
+ {
+ ...cnCard.api.value,
+ },
+ false,
+ )
+
+ let cnActive = (
+ await CrowdNode.http.IsAddressInUse(cnShareAccount.address)
+ )?.inUse
+
+ if (cnActive) {
+ let cnBalance = await CrowdNode.http.GetBalance(cnShareAccount.address)
+
+ cnCard.api.value = {
+ ...(cnCard.api.value || {}),
+ balance: cnBalance?.TotalBalance || 0,
+ earned: cnBalance?.TotalDividend || 0,
+ }
+ }
+
+ let cnAddr = await store.addresses.getItem(
+ cnShareAccount.address
+ )
+
console.log(
- `confirm action`,
+ `CN confirm action`,
{state, fde, cbConfAct},
)
- let cnFunding = await showQrCode({
- name: 'CrowdNode Funding',
- amount: 1.1,
- status: DIALOG_STATUS.LOADING,
- generateNextAddress: state => html`
- Send 1.1 Dash or more
- to signup & fund your CrowdNode account.
- `,
- footer: state => html`
-
- `,
- })
+ let cnFunding
+ let neededFunds = roundUsing(
+ Math.ceil,
+ minimumNeededFunds - walletFunds.balance,
+ 3
+ )
+
+ if (
+ cnCard.api.value.balance === 0 &&
+ (!cnAddr?.insight?.balance ||
+ cnAddr.insight.balance < minimumNeededFunds)
+ ) {
+ if (
+ walletFunds.balance < minimumNeededFunds
+ ) {
+ cnFunding = await showQrCode({
+ wallet: cnShareAccount,
+ name: 'CrowdNode Funding',
+ amount: neededFunds,
+ status: DIALOG_STATUS.LOADING,
+ fieldsetHeader: state => html`
+ Send ${neededFunds} Dash or more
+ to signup & fund your CrowdNode account.
+ `,
+ footer: state => html`
+
+ `,
+ })
+ } else {
+ // Show Confirmation Dialog to redistribute
+ // funds to the correct address
+ console.warn(
+ 'wallet has sufficient funds but they need to be transferred to correct address to be deposited',
+ { cnAddr, walletFunds }
+ )
+ }
+ }
state.status = DIALOG_STATUS.SUCCESS
@@ -899,11 +855,14 @@ async function main() {
console.log('CN Card Funding Callback', cnCard)
- cnCard.api.value = {
- acceptedToS: true,
- balance: 1.234,
- earned: 0.987,
- }
+ appTools.storedData?.encryptItem?.(
+ store.integrations,
+ 'crowdnode',
+ {
+ ...cnCard.api.value,
+ },
+ false,
+ )
cnCard.render({
cfg,
@@ -928,6 +887,73 @@ async function main() {
appDialogs.confirmAction.showModal()
}
+ if (fde.intent === 'fund') {
+ if (
+ walletFunds.balance < minimumNeededFunds
+ ) {
+ let neededFunds = roundUsing(
+ Math.ceil,
+ minimumNeededFunds - walletFunds.balance,
+ 3
+ )
+ let cnFunding = await showQrCode({
+ wallet,
+ name: 'CrowdNode Funding',
+ amount: neededFunds,
+ status: DIALOG_STATUS.LOADING,
+ fieldsetHeader: state => html`
+ Send ${neededFunds} Dash or more
+ to signup & fund your CrowdNode account.
+ `,
+ footer: state => html`
+
+ `,
+ })
+
+ console.log(
+ `confirm action SUCCESS`,
+ {fde, cnFunding},
+ )
+ } else {
+ // Show Confirmation Dialog to redistribute
+ // funds to the correct address
+ console.warn(
+ 'wallet has sufficient funds but they need to be transferred to correct address to be deposited',
+ { cnAddr, walletFunds, wallet }
+ )
+ appDialogs.sendOrReceive?.elements?.form?.classList.add?.('min-h-auto')
+ await appDialogs.sendOrReceive.render({
+ name: 'Consolidate Funds for CrowdNode',
+ actionTxt: 'Consolidate',
+ actionAlt: 'Consolidate Funds',
+ action: 'consolidate', // fde.intent,
+ actionType: 'infoo',
+ placement: 'center auto-height',
+ cashSend: () => html`
+
+ `,
+ hideAddressee: true,
+ wallet,
+ // wallet: cnShareAccount,
+ userInfo,
+ // account: appState.account,
+ // contacts: appState.contacts,
+ to: cnShareAccount.address,
+ })
+ appDialogs.sendOrReceive.showModal()
+ }
+ }
+
console.log(
`Crowdnode Card submit TX`,
fde.intent,
@@ -938,9 +964,11 @@ async function main() {
appDialogs.sendOrReceive?.elements?.form?.classList.add?.('min-h-auto')
await appDialogs.sendOrReceive.render({
name: 'Deposit to CrowdNode',
+ actionTxt: 'Deposit',
+ actionAlt: 'Deposit to CrowdNode',
cashSend: () => html``,
hideAddressee: true,
- action: fde.intent,
+ action: 'send', // fde.intent,
wallet,
account: appState.account,
userInfo,
@@ -949,6 +977,7 @@ async function main() {
})
appDialogs.sendOrReceive.showModal()
}
+
if (fde.intent === 'withdraw') {
crowdnodeTransactionRig.markup.fields = html`
@@ -1014,7 +1043,9 @@ async function main() {
},
},
})
+
cnWithdraw?.elements?.form?.classList.add?.('min-h-auto')
+
crowdnodeTransactionRig.markup.footer = html`
//
// `)
+ appState.encryptionPassword = window.atob(
+ sessionStorage.encryptionPassword || ''
+ )
+ appState.selectedAlias = localStorage?.selectedAlias || ''
+ appState.selectedAccount = localStorage?.selectedAccount || ''
+ appState.selectedWallet = localStorage?.selectedWallet || ''
let txs = await getTxs(
appState,
Object.values(appState.transactions || {})
)
+ // Load Cached TXs
await transactionsList.render({
userInfo,
contacts: appState.contacts,
transactions: Object.values(txs.byTx),
})
+ // Update TX Cache
txs = await getTxs(appState)
- console.log('main getTxs', txs)
-
+ // Re-Render TXs with Updated Cache
transactionsList.render({
userInfo,
contacts: appState.contacts,
@@ -1117,6 +1162,7 @@ async function main() {
aliasTarg?.nextElementSibling.classList.toggle('hidden')
}
+
if (id === 'nav-edit-profile') {
event.preventDefault()
event.stopPropagation()
@@ -1135,6 +1181,7 @@ async function main() {
)
appDialogs.editProfile.showModal()
}
+
if (id === 'nav-backup') {
event.preventDefault()
event.stopPropagation()
@@ -1151,6 +1198,7 @@ async function main() {
)
appDialogs.walletBackup.showModal()
}
+
if (id === 'nav-lock') {
event.preventDefault()
event.stopPropagation()
@@ -1172,6 +1220,7 @@ async function main() {
})
appDialogs.confirmAction.showModal()
}
+
if (id === 'nav-disconnect') {
event.preventDefault()
event.stopPropagation()
@@ -1419,6 +1468,8 @@ async function main() {
}
},
})
+
+ await getUserInfo()
}
main()
diff --git a/src/models/contacts.js b/src/models/contacts.js
new file mode 100644
index 0000000..0752ebd
--- /dev/null
+++ b/src/models/contacts.js
@@ -0,0 +1,262 @@
+import {
+ OIDC_CLAIMS,
+} from '../utils/constants.js'
+
+import {
+ appState,
+ appTools,
+ store,
+ wallets,
+ getStoredWallet,
+ getUnusedAccountIndex,
+} from '../state/index.js'
+
+import {
+ getUniqueAlias,
+ getContactAliases,
+ deriveWalletData,
+ batchGenAcctAddrs,
+ parseAddressField,
+} from '../utils/dash/local.js'
+
+// Create & Update Contact
+
+export async function parseContactURI(uri) {
+ let data = {
+ uri,
+ }
+
+ if (uri?.length >= 34) {
+ // let incoming = {}
+ let outgoing = {}
+
+ let {
+ address,
+ xpub,
+ xprv,
+ name,
+ preferred_username,
+ sub,
+ } = parseAddressField(uri)
+
+ let xkey = xprv || xpub
+
+ let xkeyOrAddr = xkey || address
+
+ let info = {
+ name,
+ sub,
+ preferred_username,
+ }
+
+ let alias = await getUniqueAlias(
+ getContactAliases(),
+ preferred_username
+ )
+
+ if (!xkey && address) {
+ outgoing = {
+ [address]: {
+ address,
+ },
+ }
+ }
+
+ if (xkey) {
+ let {
+ xkeyId,
+ addressKeyId,
+ addressIndex,
+ address: addr,
+ } = await deriveWalletData(
+ xkey,
+ )
+
+ outgoing = {
+ [xkeyId]: {
+ addressIndex,
+ addressKeyId,
+ address: address || addr,
+ xkeyId,
+ xprv,
+ xpub,
+ },
+ }
+ }
+
+ data = {
+ uri,
+ alias,
+ name,
+ info,
+ outgoing,
+ xkeyOrAddr,
+ preferred_username,
+ }
+ }
+
+ // console.log(
+ // 'parseContactURI',
+ // data,
+ // )
+
+ return data
+}
+
+export async function putContact(
+ data = {},
+) {
+ let selectedWallet = getStoredWallet()
+ let accountIndex = getUnusedAccountIndex(selectedWallet)
+ // TODO: find Account Index With No TXs
+
+ let shareAccount
+ let parsedUri = {}
+
+ if (appState.phrase) {
+ console.log(
+ 'addContact current wallet',
+ accountIndex,
+ selectedWallet?.xkeyId,
+ selectedWallet,
+ )
+
+ if (selectedWallet) {
+ let upWallet = await store.wallets.setItem(
+ localStorage.selectedWallet,
+ {
+ ...selectedWallet,
+ accountIndex,
+ updatedAt: (new Date()).toISOString(),
+ }
+ )
+ wallets[localStorage.selectedWallet] = upWallet
+ }
+
+ shareAccount = await deriveWalletData(
+ appState.phrase,
+ accountIndex,
+ )
+
+ let created = (new Date()).toISOString()
+ // let updated = (new Date()).toISOString()
+ let usage = [0,0]
+
+ let newAccount = await store.accounts.setItem(
+ shareAccount.xkeyId,
+ {
+ createdAt: created,
+ updatedAt: created,
+ accountIndex,
+ usage,
+ walletId: shareAccount.id,
+ xkeyId: shareAccount.xkeyId,
+ addressKeyId: shareAccount.addressKeyId,
+ address: shareAccount.address,
+ }
+ )
+ let { createdAt, updatedAt, ...contactAcct } = newAccount
+
+ let { addresses, finalAddressIndex } = await batchGenAcctAddrs(
+ shareAccount,
+ newAccount,
+ ) ?? {}
+
+ console.log(
+ 'addContact derived wallet',
+ {
+ accountIndex,
+ finalAddressIndex,
+ addresses,
+ shareAccount,
+ newAccount,
+ }
+ )
+
+ if (data.uri) {
+ // { address, xpub, xprv, name, preferred_username, sub, }
+ parsedUri = await parseContactURI(data.uri)
+ }
+
+ console.log('addContact', {parsedUri})
+
+ let alias = await getUniqueAlias(
+ getContactAliases(),
+ data.alias
+ )
+
+ let newContact = await appTools.storedData.encryptItem(
+ store.contacts,
+ shareAccount.xkeyId,
+ storedContact => ({
+ createdAt,
+ updatedAt: (new Date()).toISOString(),
+ incoming: {
+ [`${contactAcct.walletId}/${contactAcct.xkeyId}`]: {
+ ...contactAcct,
+ }
+ },
+ outgoing: {
+ ...(parsedUri.outgoing || {})
+ },
+ info: {
+ ...OIDC_CLAIMS,
+ ...(storedContact.info || {}),
+ sub: parsedUri?.sub || '',
+ ...(data.info || {}),
+ preferred_username: data.alias || '',
+ // @ts-ignore
+ // sub: contactAcct.xkeyId,
+ // sub: data.info?.sub || '',
+ // name: data.info?.name || '',
+ },
+ uri: data.uri || '',
+ alias,
+ }),
+ // false,
+ )
+
+ // await contactsList.render({
+ // userInfo,
+ // contacts: appState.contacts,
+ // })
+
+ console.log(
+ 'addContact',
+ {
+ newAccount,
+ shareAccount,
+ newContact,
+ },
+ )
+
+ return {
+ newAccount,
+ shareAccount,
+ newContact,
+ }
+ }
+}
+
+// Find Contact(s)
+export async function findContactByXkeyID(xkeyId) {
+ let contact = appState.contacts.find(
+ c => Object.keys(c.incoming).find(i => i.endsWith(xkeyId))
+ )
+ // console.log('find contact by XkeyID', { contact })
+ return contact
+ // return await appTools.storedData.decryptItem(
+ // store.contacts,
+ // xkeyId,
+ // )
+}
+
+export async function findContactByAlias(alias) {
+ let contact = appState.contacts.find(c => c.alias === alias)
+ console.log('find contact by alias', { contact })
+ return contact
+}
+
+// Remove Contact(s)
+
+// List Contacts
\ No newline at end of file
diff --git a/src/rigs/add-contact.js b/src/rigs/add-contact.js
index 80907fb..736c1b2 100644
--- a/src/rigs/add-contact.js
+++ b/src/rigs/add-contact.js
@@ -15,16 +15,18 @@ import {
getStoreData,
} from '../utils/db.js'
-import { qrSvg } from '../utils/qr.js'
-
import {
- deriveWalletData,
- parseAddressField,
generateContactPairingURI,
- getUniqueAlias,
- isUniqueAlias,
} from '../utils/dash/local.js'
+import {
+ processURI,
+} from '../utils/dash/network.js'
+
+import * as model from '../models/contacts.js'
+
+import { qrSvg } from '../utils/qr.js'
+
export let addContactRig = (async function (globals) {
'use strict';
@@ -92,198 +94,6 @@ export let addContactRig = (async function (globals) {
)
}, 1000)
- async function processURI(state, target, value) {
- let {
- address,
- xpub,
- xprv,
- name,
- preferred_username,
- sub,
- } = parseAddressField(value)
-
- let xkey = xprv || xpub
-
- let xkeyOrAddr = xkey || address
-
- let info = {
- name: name || '',
- sub,
- preferred_username,
- }
-
- let preferredAlias = await getUniqueAlias(
- aliases,
- preferred_username
- )
-
- let outgoing = {}
-
- let existingContacts
- let contactWallet
-
- if (!xkey && address) {
- existingContacts = appState.contacts.filter(
- c => c.outgoing?.[address]
- )
-
- outgoing = {
- ...(state.contact.outgoing || {}),
- [address]: {
- address,
- },
- }
- }
-
- if (xkey) {
- contactWallet = await deriveWalletData(
- xkey,
- )
- let {
- xkeyId,
- addressKeyId,
- addressIndex,
- address: addr,
- } = contactWallet
-
- existingContacts = appState.contacts.filter(
- c => c.outgoing?.[xkeyId]
- )
-
- outgoing = {
- ...(state.contact.outgoing || {}),
- [xkeyId]: {
- addressIndex,
- addressKeyId,
- address: address || addr,
- xkeyId,
- xprv,
- xpub,
- },
- }
-
- // console.log(
- // 'add contact handleInput parsedAddr',
- // value,
- // xkey,
- // )
- }
-
- let newContact
-
- if (existingContacts?.length > 0) {
- console.warn(
- `You've already paired with this contact`,
- {
- existingContacts,
- newContact: {
- alias: preferredAlias,
- outgoing,
- }
- }
- )
-
- // newContact = existingContacts[0]
-
- let pairings = existingContacts.map(c => `@${c.alias}`)
- if (pairings.length > 1) {
- let lastPairing = pairings.pop()
- pairings = `${pairings.join(', ')} & ${lastPairing}`
- } else {
- pairings = pairings[0]
- }
-
- // TODO: maybe prompt to show original pairing info
- // in the scenario where your contact
- // lost their contacts list
- target.contactAddr.setCustomValidity(
- `You've already paired with this contact (@${preferred_username}) as ${pairings}`,
- )
- target.reportValidity()
- return;
- } else {
- if (Object.keys(outgoing).length > 0 && contactWallet) {
- let xkeyAddrs = await batchXkeyAddressGenerate(
- contactWallet,
- contactWallet.addressIndex,
- )
- let contactAddrs = {}
- let addresses = xkeyAddrs.addresses.map(g => {
- contactAddrs[g.address] = {
- alias: preferredAlias,
- xkeyId: contactWallet.xkeyId,
- }
- return g.address
- })
-
- let txs = await getAddrsTransactions({
- appState,
- addrs: addresses,
- contactAddrs,
- })
-
- // outgoing[contactWallet.xkeyId] = {
- // ...(outgoing[contactWallet.xkeyId] || {}),
- // addressIndex: xkeyAddrs.finalAddressIndex,
- // }
-
- // console.log('xkeyAddrs', {addresses, txs})
- }
-
- newContact = await appTools.storedData.encryptItem(
- store.contacts,
- state.wallet.xkeyId,
- {
- ...state.contact,
- updatedAt: (new Date()).toISOString(),
- info: {
- ...OIDC_CLAIMS,
- ...(state.contact.info || {}),
- ...info,
- },
- outgoing,
- alias: preferredAlias,
- uri: value,
- },
- false,
- )
-
- getStoreData(
- store.contacts,
- res => {
- if (res) {
- appState.contacts = res
-
- return contactsList.restate({
- contacts: res,
- userInfo,
- })
- }
- },
- res => async v => {
- res.push(await appTools.storedData.decryptData(v))
- }
- )
-
- state.contact = newContact
-
- if (value) {
- target.contactURI.value = value
- }
- if (xkeyOrAddr) {
- target.contactAddr.value = xkeyOrAddr
- }
- if (name) {
- target.contactName.value = name
- }
- if (preferred_username) {
- target.contactAlias.value = preferredAlias
- }
- }
-
- return
- }
-
let addContact = await setupDialog(
mainApp,
{
@@ -462,7 +272,7 @@ export let addContactRig = (async function (globals) {
// )
if (
startAlias !== event.target?.value &&
- !isUniqueAlias(aliases, event.target?.value)
+ !aliases[event.target?.value]
) {
event.target.setCustomValidity(
'Alias already used. A unique alias is required.'
@@ -594,9 +404,10 @@ export let addContactRig = (async function (globals) {
event.target.reportValidity()
return;
}
+
if (
startAlias !== currentAlias &&
- !isUniqueAlias(aliases, currentAlias)
+ !aliases[currentAlias]
) {
event.target.contactAlias.setCustomValidity(
'Alias already used. A unique alias is required.'
@@ -605,54 +416,12 @@ export let addContactRig = (async function (globals) {
return;
}
- let storedContact = await appTools.storedData.decryptItem(
- store.contacts,
- state.wallet.xkeyId,
- )
- let pairedContact = appTools.storedData.encryptItem(
- store.contacts,
- state.wallet.xkeyId,
- {
- ...storedContact,
- updatedAt: (new Date()).toISOString(),
- info: {
- // ...OIDC_CLAIMS,
- ...(storedContact.info || {}),
- // @ts-ignore
- sub: parsedAddr?.sub || '',
- name: event.target.contactName.value,
- },
- uri: event.target.contactURI.value,
- alias: currentAlias || event.target.contactAlias.value,
+ model.putContact({
+ info: {
+ name: event.target.contactName.value,
},
- false,
- )
-
- pairedContact.then(pc => {
- // console.log('pairedContact', pc)
-
- getStoreData(
- store.contacts,
- res => {
- if (res) {
- appState.contacts = res
-
- updateAllFunds(state.wallet)
- .then(funds => {
- // console.log('updateAllFunds then funds', funds)
- })
- .catch(err => console.error('catch updateAllFunds', err, state.wallet))
-
- return contactsList.restate({
- contacts: res,
- userInfo,
- })
- }
- },
- res => async v => {
- res.push(await appTools.storedData.decryptData(v))
- }
- )
+ alias: currentAlias || event.target.contactAlias.value,
+ uri: event.target.contactURI.value,
})
addContact.close()
diff --git a/src/rigs/edit-contact.js b/src/rigs/edit-contact.js
index 97898b8..ce36754 100644
--- a/src/rigs/edit-contact.js
+++ b/src/rigs/edit-contact.js
@@ -18,7 +18,6 @@ import {
deriveWalletData,
parseAddressField,
getUniqueAlias,
- isUniqueAlias,
} from '../utils/dash/local.js'
export let editContactRig = (async function (globals) {
@@ -349,7 +348,7 @@ export let editContactRig = (async function (globals) {
) {
if (
startAlias !== event.target?.value &&
- !isUniqueAlias(aliases, event.target?.value)
+ !aliases[event.target?.value]
) {
event.target.setCustomValidity(
'Alias already used. A unique alias is required.'
@@ -477,7 +476,7 @@ export let editContactRig = (async function (globals) {
}
if (
startAlias !== currentAlias &&
- !isUniqueAlias(aliases, currentAlias)
+ !aliases[currentAlias]
) {
event.target.contactAlias.setCustomValidity(
'Alias already used. A unique alias is required.'
diff --git a/src/rigs/phrase-generate.js b/src/rigs/phrase-generate.js
index c2ff9fa..8c9bbf9 100644
--- a/src/rigs/phrase-generate.js
+++ b/src/rigs/phrase-generate.js
@@ -93,10 +93,9 @@ export let phraseGenerateRig = (async function (globals) {
wallet = await generateWalletData()
appState.phrase = wallet.recoveryPhrase
- appState.selectedWallet = wallet.id
appState.selectedAlias = `${fde.alias}`
- localStorage.selectedWallet = appState.selectedWallet
+ localStorage.selectedWallet = wallet.id
localStorage.selectedAlias = appState.selectedAlias
let usage = [0,0]
diff --git a/src/rigs/phrase-import.js b/src/rigs/phrase-import.js
index 5e81336..d75524d 100644
--- a/src/rigs/phrase-import.js
+++ b/src/rigs/phrase-import.js
@@ -60,10 +60,10 @@ export let phraseImportRig = (async function (globals) {
state.elements.form.alias.value = appState.selectedAlias
- appState.selectedWallet = Object.keys(
+ localStorage.selectedWallet = Object.keys(
res.wallets
)?.[0]
- localStorage.selectedWallet = appState.selectedWallet
+ appState.selectedWallet = wallet.id
} else {
console.log('kestore file', { res, file })
state.keystoreData = res
@@ -476,8 +476,8 @@ export let phraseImportRig = (async function (globals) {
wallet = await deriveWalletData(appState.phrase)
+ localStorage.selectedWallet = wallet.id
appState.selectedWallet = wallet.id
- localStorage.selectedWallet = appState.selectedWallet
let usage = [0,0]
// usage[wallet.usageIndex] = wallet.addressIndex
diff --git a/src/rigs/request-qr.js b/src/rigs/request-qr.js
index 72b92a0..1bc8499 100644
--- a/src/rigs/request-qr.js
+++ b/src/rigs/request-qr.js
@@ -1,3 +1,7 @@
+import {
+ DEFAULT_ENTRYPOINT,
+} from '../utils/constants.js'
+
import {
lit as html,
formDataEntries,
@@ -6,6 +10,9 @@ import {
} from '../utils/generic.js'
import {
+ store,
+ batchGenAcctAddrs,
+ deriveWalletData,
generatePaymentRequestURI,
getPartialHDPath,
getAddressIndexFromUsage,
@@ -13,16 +20,22 @@ import {
import { qrSvg } from '../utils/qr.js'
+import {
+ appState,
+ appDialogs,
+ appTools,
+ userInfo,
+} from '../state/index.js'
+
+import setupDialog from '../components/dialog.js'
+
export let requestQrRig = (async function (globals) {
'use strict';
- let {
- mainApp, appDialogs, appState, appTools, userInfo, store,
- setupDialog, deriveWalletData, batchGenAcctAddrs,
- } = globals;
+ console.log('requestQrRig', {globals})
let requestQr = await setupDialog(
- mainApp,
+ DEFAULT_ENTRYPOINT,
{
name: 'Share to receive funds',
address: '',
@@ -39,25 +52,6 @@ export let requestQrRig = (async function (globals) {
footer: state => html`