MetaweaveTeam / arweave-account

Account protocol library on Arweave by Metaweave.xyz
https://www.npmjs.com/package/arweave-account
15 stars 10 forks source link

Extend Account to add appSpecific features #3

Open twilson63 opened 2 years ago

twilson63 commented 2 years ago
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

The following options in the constructor are required

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 commented 2 years ago

Discussion history

cromatikap commented 2 years ago

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

It involves few changes on src/index.ts:

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 commented 2 years ago

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 commented 2 years ago

You can see the error here:

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

anthonyra commented 1 year ago

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.