Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Account to add appSpecific features #3

Open
6 tasks
twilson63 opened this issue May 15, 2022 · 5 comments
Open
6 tasks

Extend Account to add appSpecific features #3

twilson63 opened this issue May 15, 2022 · 5 comments

Comments

@twilson63
Copy link
Contributor

twilson63 commented May 15, 2022

As an dApp Developer
I want to integrate arweave-account into my dApp 
and store dApp specific content per `account`
so that the user can own their dApp configuration information

The following API methods are required

  • account.appData.set(item, value)
  • account.appData.get(item | undefined) if undefined, get all items
  • account.appData.remove(item)
  • account.appData.clear()

The following options in the constructor are required

  • AppIdentifier: string | undefined
  • Arweave: ArweaveObj | undefined

Examples

const account = new Account({
    AppIdentifier: "permanotes",
    Arweave: ArweaveObj                // wallet connection & tx signing
})

// add profile to follow
const following = await account.appData.get('following')
await account.appData.set('following', ['rakis', ...following])

// add topic to subscribe
const subscriptions = await account.appData.get('subscriptions')
await account.appData.set('subscriptions', ['arweave-dev', ...subscriptions])
const account = new Account({
    AppIdentifier: "metaweave",
    Arweave: ArweaveObj                // wallet connection & tx signing
})

// add profile to follow
const trustedWallets = await account.appData.get('trusted-wallets')
await account.appData.set('trusted-wallets', [
  'vh-NTHVvlKZqRxc8LyyTNok65yQ55a_PJ1zWLb9G2JI',
  ...trustedWallets
])
@cromatikap
Copy link
Contributor

Discussion history

@cromatikap
Copy link
Contributor

Hello!
I updated the LSCache.ts to Cache/ so it is now compatible for nodejs projects

It involves few changes on src/index.ts:

  • cache object value is null if the cache is deactivated
  • clearCache() has been replaced by debug: { resetCache(), dumpCache() }
  • I have npm run lint & npm run format :)

Full diff here:

 import Arweave from 'arweave';
 import ArDB from 'ardb';
-import { T_account, T_addr, T_profile, T_txid } from './types';
+import { T_account, T_addr, T_txid } from './types';
 import transaction from 'ardb/lib/models/transaction';
 import block from 'ardb/lib/models/block';
-import LSCache from './LSCache';
+import Cache from './Cache';
 
 export default class Account {
   private arweave: Arweave;
   private ardb: ArDB;
-  private cache: LSCache;
+  private cache: Cache | null;
 
   constructor({
-    cache = true,
+    cacheIsActivated = true,
     cacheSize = 100,
     cacheTime = 60000,
     gateway = {
@@ -24,13 +24,18 @@ export default class Account {
   } = {}) {
     this.arweave = Arweave.init(gateway);
     this.ardb = new ArDB(this.arweave);
-    this.cache = new LSCache(cache, cacheSize, cacheTime);
+
+    if (cacheIsActivated) {
+      if (typeof window !== 'undefined') {
+        this.cache = new Cache('web', cacheSize, cacheTime);
+      } else this.cache = new Cache('node', cacheSize, cacheTime);
+    } else this.cache = null;
   }
 
   async get(addr: T_addr): Promise<T_account | null> {
     addr = addr.trim();
-    let cacheResponse;
-    if ((cacheResponse = this.cache.get(addr))) return cacheResponse;
+    const cacheResponse = this.cache?.get(addr);
+    if (cacheResponse !== undefined) return cacheResponse;
     else {
       const tx: transaction[] | block[] = await this.ardb
         .search('transactions')
@@ -46,17 +51,17 @@ export default class Account {
         profile = {
           ...profile,
           handle: `${profile.handle}#${addr.slice(0, 3)}${addr.slice(addr.length - 3)}`,
-          addr: addr,
+          addr,
         };
         const account = {
           txid: tx[0].id,
           profile,
         };
 
-        this.cache.hydrate(addr, account);
+        this.cache?.hydrate(addr, account);
         return account;
       } else {
-        this.cache.hydrate(addr);
+        this.cache?.hydrate(addr);
         return null;
       }
     }
@@ -84,7 +89,7 @@ export default class Account {
         handle: `${profile.handle}#${addr.slice(0, 3)}${addr.slice(addr.length - 3)}`,
       };
       return {
-        txid: txid,
+        txid,
         profile,
       } as T_account;
     });
@@ -100,12 +105,12 @@ export default class Account {
   }
 
   async find(uniqueHandle: string): Promise<T_account | null> {
-    let cacheResponse;
     uniqueHandle = uniqueHandle.trim();
     // check if format is handle#xxxxxx
     if (!/^(.+)#[a-zA-Z0-9\-\_]{6}$/.test(uniqueHandle)) return null;
 
-    if ((cacheResponse = this.cache.find(uniqueHandle))) return cacheResponse;
+    const cacheResponse = this.cache?.find(uniqueHandle);
+    if (cacheResponse !== undefined) return cacheResponse;
     else {
       const txs: transaction[] | block[] = await this.ardb
         .search('transactions')
@@ -118,32 +123,44 @@ export default class Account {
         const txid: T_txid = tx.id;
         let profile = (
           await this.arweave.api.get(txid).catch(() => {
-            return { data: null };
+            return { data: null };
           })
         ).data;
         const addr = 'owner' in tx ? tx.owner.address : 'anonymous';
-        profile = {
-          ...profile,
-          addr,
-          handle: `${profile.handle}#${addr.slice(0, 3)}${addr.slice(addr.length - 3)}`,
-        };
-        return {
-          txid: txid,
-          profile,
-        } as T_account;
+
+        if (uniqueHandle === `${profile.handle}#${addr.slice(0, 3)}${addr.slice(addr.length - 3)}`) {
+          profile = {
+            ...profile,
+            addr,
+            handle: `${profile.handle}#${addr.slice(0, 3)}${addr.slice(addr.length - 3)}`,
+          };
+          return {
+            txid,
+            profile,
+          } as T_account;
+        }
       });
 
       const a = await Promise.all(formattedAccounts);
-      const accounts = a.filter((e): e is T_account => e !== null);
+      const accounts = a.filter((e): e is T_account => e !== undefined);
 
       if (accounts.length > 0) {
-        this.cache.hydrate(accounts[0].profile.addr, accounts[0]);
+        this.cache?.hydrate(accounts[0].profile.addr, accounts[0]);
         return accounts[0];
       } else return null;
     }
   }
 
-  clearCache(): void {
-    this.cache.reset();
-  }
+  public debug = {
+    resetCache: (): void => {
+      this.cache?.reset();
+    },
+    printCache: (): void => {
+      const now = new Date();
+      // tslint:disable-next-line
+      console.log(` > Cache content at ${now.toISOString().replace(/T/, ' ').replace(/\..+/, '')}\n`);
+      // tslint:disable-next-line
+      console.log(this.cache?.dump());
+    },
+  };
 }

Sorry for the inconvenience

@twilson63
Copy link
Contributor Author

Cool, I updated my account rakis and now I am getting another error with getData this time on the get account method, ok if I change getData to get on the account.get method?

@twilson63
Copy link
Contributor Author

You can see the error here:

Screen Shot 2022-05-16 at 9 21 10 AM

twilson63 added a commit to twilson63/arweave-account that referenced this issue May 20, 2022
twilson63 added a commit to twilson63/arweave-account that referenced this issue May 20, 2022
twilson63 added a commit to twilson63/arweave-account that referenced this issue May 20, 2022
@anthonyra
Copy link

anthonyra commented Feb 7, 2023

Can I bump this? 😅 I would really like to include this in my dApp.

Also not sure how much it's worth but, I prefer the storage or arStorage designation vs the appData ... unless you'd have the following functionality account.appData.myApp.set but if it's mimicing localStorage than account.arStorage.set makes sense to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants