---
# System prepended metadata

title: Haus SDK Spec Rage
tags: [' scratch', v3]

---

---
tags: v3, scratch
---

# Haus SDK Spec Rage

## Goals

Create rage versions of new packages to make suggestions about
- types of libraries and their concerns
- project/folder structure
- some initial examples of the api/interfaces for the SDK related libraries



---


### Libraries

Recommend we break libraries into the following functional types:


| UI                                                | Features                                                                                                    | Data-access                                  | Utilities                                          |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -------------------------------------------------- |
| purely presentational components                  | smart components wrapping data sdk, component library, web3 libraries                               | data fetching, transformation for the client | functions/utilities used across libraries and apps |
| **@daohaus/ui** (the component library)  | haus smart components ex: proposalList, connectWallet  | **@daohaus/sdk**|**@daohaus/utils**|
| | other ideas: redux wrapper, react hooks| | goal here to break up utilities into many smaller/hyper focussed pkgs, ex: local abis 

***@daohaus/ui or @haus/ui***

I initially had some concerns that breaking these libraries into many small packages would increase the complexity of managing them, but I think our nx mono-repo makes this easier, and there are some solid benefits, ie)
- easier for developers to understand what library to use and what it will do
- smaller packages/bundles


*This spec will continue with the data-access and utility library exploration only. find UI library details here:*
[https://hackmd.io/Wk5hjmerSqKfXx0dp0DJfA](https://hackmd.io/Wk5hjmerSqKfXx0dp0DJfA)
[https://hackmd.io/6Ei1TcsdSb2LQeQzW0jumQ](https://hackmd.io/6Ei1TcsdSb2LQeQzW0jumQ)



---


### Package structures

#### @daohaus/haus-sdk scope

This package will have a single class exposed. We can add smaller functional classes within that as needs emerge.

**haus class**
- inits the library w/ subclasses for scoped functionality

**query class**
- scoped/curated queries w/ full data hydration
    - ex: computing proposal status
    - can pull from multiple data sources
        - subgraphs, lambda/skynet cache, ceramic/idx, other 3rd party apis
    - queries grouped by functional area
        - user address, dao, proposals, members, vault data/balances
    - support 
    
    /filtering on list queries
- generic query function taking in raw graphql args
    - enables greater flexibility
    - urql wrapper taking typical query params
    - no hydration or light hydration because we can't predict the fields asked for
        - maybe just subgraph fields
    - user needs to handle pagination/filtering
    
**other class ideas**
- transaction
- contract? expose some raw contract calls for getting - or does this belong in query?

**utils directory**
- utils hyper only used in sdk
    - requests
    - data transformation/hydration
    - gql queries

**types directory**

##### folder structure
```
.
├── src/
│   ├── index.ts
│   ├── query.ts
│   ├── haus.ts
│   ├── utils/
│   │   ├── index.ts
│   │   ├── requests.ts
│   │   └── someother-sdk-only-util.ts
│   └── types/
│       └── index.ts
│       └── some-type-domain.ts
└── test/
    └── some.spec.ts
```

*Base index.ts only imports/exports the haus class and types. *
```javascript
import Haus from "./sdk";

export { Haus };

export * from "./types";
```


##### interface sketch

```javascript

import Haus from '@daohaus/haus-sdk';

const haus = await Haus.create({
  0x64: 'some provider url',
  0x4: 'some other provider url' 
});

const daoData = await haus.query.dao('some dao address', '0x64');

const userDaos = await haus.query.userDaos('some user address')

const customQuery = await haus.graphQuery({
    network: '0x64', 
    query: SOME_GQL_QUERY, 
    fields: 'id,createdAt,proposalId'
});

```

#### [rage repo](https://github.com/HausDAO/daohaus-rage/tree/rage/sdk/libs/haus-sdk-rage)


---


#### @daohaus/haus-utils

Grouped functions, constants, types  

- constants
    - legos
    - endpoints
    - contract addresses
    - contract abis
    - general contstant values grouped by functional area, ex: proposal types

- utils
    - all reused utils (functions, anything else we find ourselves using often across apps)
    - **TODO: need to review V2 and upcoming V3 to try and get a larger list and organize by functional area. But some of these will emerge as we build**
        - would an audit be helpful at this point -- creating an ongoing list?
        - this can then become the TODO list and as folks are Raging/Saging they would mark it off the list -- it can then be added to our `utils`
- types
    - we can add types as we identify ones that are useful across packages/apps

##### folder structure
```
.
├── src/
│   ├── index.ts
│   ├── constants/
│   │   ├── index.ts
│   │   ├── some-constants.ts
│   │   └── some-other-grouped-constants.ts
│   └── types/
│       ├── index.ts
│       └── some-type-domain.ts
└── test/
    └── some.spec.ts
```

Base index.ts export * from all it's directories 
- makes every function available on it's own
Directory index.ts export * from all it's friends
- can not export anything here that we don't want exposed outside the library


##### interface sketch

```javascript

import { encodeParams, PROPOSAL_STATUSES } from '@daohaus/haus-commons';

const encodedParams = encodeParams(someArgs);

console.log(PROPOSAL_STATUSES)

>>>>
// {
//   unsponsored: 'Unsponsored',
//   voting: 'Voting',
//   grace: 'Grace',
//   expired: 'Expired',
//   cancelled: 'Cancelled',
//   needsProcessing: 'Ready for Processing',
//   failed: 'Failed',
//   passed: 'Passed',
//   actionFailed: 'Processing Failed',
//   unknown: 'Unknown',
// };

```

#### [rage repo](https://github.com/HausDAO/daohaus-rage/tree/rage/sdk/libs/haus-parlor)



## Pagination notes



#### Query API:

```javascript=
haus.query.listDaos({networkId: '0x5', pagination: {type: 'offset', pageSize: 100}})

haus.query.listDaos({networkId: '0x5', pagination: {type: 'cursor', pageSize: 100}})

// fetch all
haus.query.listDaos({networkId: '0x5', pagination: {type: 'all'}})
```

**types of pagination**

offset:
- can be used with any sort order
- bad for large data sets
    - skip is limited ~6000
    - poor performance
- where: {id_gt: "0x3c56b96061bc34ba4d07d9bb1166b2297e1cf342-proposal-3"}
- TODO: first might have an upper limit of 2000 we'd need to protect against

cursor:
- requires sort order to be on a field with ascending order
    - overrides sort by - sorts by id
    - throw error if they send an order

all:
- uses cursor pagination and loops through until no records are found




#### Response

```typescript=
export interface QueryResult<Data = any> {
  data?: Data;
  error?: HausError;
  networkId?: keyof Keychain;
  queryOptions: QueryOptions;  
  pagination?: PaginationOptions;
  page?: number;
  fetchPrevious?: Function;
  fetchNext?: Function  
    
    /// trackLastId on cursor
}

```

- pagination
    - stores the original pagination object used in the query, updates in subsequent calls
        - 1st page: {type: 'offset', pageSize: 100, skip: 0}
        - 2nd page: {type: 'offset', first: 100, skip: 100}
    - we always up the 'first' by 1, but only return what was requested, so we can see if there is a next page or not

- page: count the page up and down

- fetch functions
    - null if there isn't another page
    - function definitions if there is to call the fetch again and update the pagination obkect and page count
        - can we provide a properly scoped sdk function in this res?

```javascript=
const res = haus.query.listDaos({networkId: '0x5', filter: {dao: '0x0'}, pagination: {type: 'offset', first: 3, skip: 0}})

// {
//     data: proposals: [1,2,3],
//     networkId: '0x5',
//     queryOptions: {filter: {dao: '0x0'}},
//     pagination: {type: 'offset', first: 3, skip: 0},
//     page: 1,
//     fetchPrevious: null,
//     fetchNext: haus.query.fetchNext,    
// }

// somthing like:
const nextRes = res.fetchNext(res);
// or
const nextRes = haus.query.fetchNext(res);

```



## Resoures

[nx library types](https://nx.dev/structure/library-types)


sdk tree
https://tree.nathanfriend.io/?s=(%27options!(%27fancy4~fullPath!false~trailingSlash4~rootDot4)~6(%276%27src*index7sdk7haus7utils*0requests705other-sdk-only-util7types*05-type-domain32test*5.spec3222%27)~version!%271%27)*200%20%202%5Cn3.ts4!true5some6source!73*%017654320*

commons tree
https://tree.nathanfriend.io/?s=(%27options!(%27fancy5~fullPath!false~trailingSlash5~rootDot5)~8(%278%27src*67*20632s3other-grouped-2s7*type063type-domain74test*A.spec7444%27)~version!%271%27)*490s*92constant3.t0A-4%5Cn5!true6index7.ts8source!9%20%20Asome%01A987654320*

[superfluid query class](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/sdk-core/src/Query.ts)
