@hivemindhq/snap 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -0
- package/dist/bundle.js +1 -0
- package/package.json +79 -0
- package/snap.manifest.json +33 -0
- package/src/images/logo.svg +7 -0
package/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Hive Mind Snap
|
|
2
|
+
|
|
3
|
+
A MetaMask Snap that displays real-time trust and reputation data from the [Intuition](https://intuition.systems) knowledge graph during transaction signing.
|
|
4
|
+
|
|
5
|
+
## What Does This Snap Do?
|
|
6
|
+
|
|
7
|
+
When you're about to send a transaction to an address, the Hive Mind Snap shows you:
|
|
8
|
+
|
|
9
|
+
- **Trust Signals** — How many people have staked that the address is trustworthy (or not)
|
|
10
|
+
- **Aliases** — Community-assigned labels for the address
|
|
11
|
+
- **Stake Amounts** — The economic weight behind each trust signal
|
|
12
|
+
- **Your Position** — Whether you've already staked on this address
|
|
13
|
+
- **dApp Origin Trust** — Trust data for the dApp you're interacting with
|
|
14
|
+
- **Trusted Circle** — See which of your trusted contacts have staked on this address
|
|
15
|
+
|
|
16
|
+
This helps you make informed decisions before interacting with unknown addresses or dApps.
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
| Feature | Description |
|
|
21
|
+
|---------|-------------|
|
|
22
|
+
| **Transaction Insights** | `onTransaction` hook displays trust data before you sign |
|
|
23
|
+
| **Trust Triple Display** | Shows support/oppose positions on `[address] has tag trustworthy` |
|
|
24
|
+
| **dApp Origin Trust** | Shows trust data for the dApp origin (transaction source) |
|
|
25
|
+
| **Trusted Circle** | Highlights when your trusted contacts have staked on an address |
|
|
26
|
+
| **Distribution Analysis** | Analyzes stake distribution health (concentrated vs. distributed) |
|
|
27
|
+
| **Alias Display** | Shows community-assigned aliases for addresses |
|
|
28
|
+
| **Multi-chain Support** | Works on Intuition Testnet (chain ID: 13579) and Mainnet (chain ID: 1155) |
|
|
29
|
+
| **Interactive UI** | Links to create trust signals or view more data on the web |
|
|
30
|
+
| **Persistent Cache** | Trusted circle cached for 1 hour for optimal performance |
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
### From npm (once published)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# The snap will be installable directly through MetaMask
|
|
38
|
+
# Package name: @hivemindhq/snap
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### For Development
|
|
42
|
+
|
|
43
|
+
See the [Development](#development) section below.
|
|
44
|
+
|
|
45
|
+
## Permissions
|
|
46
|
+
|
|
47
|
+
This Snap requires the following permissions:
|
|
48
|
+
|
|
49
|
+
| Permission | Purpose |
|
|
50
|
+
|------------|---------|
|
|
51
|
+
| `endowment:transaction-insight` | Display insights before transaction signing |
|
|
52
|
+
| `endowment:page-home` | Custom home page in MetaMask |
|
|
53
|
+
| `endowment:network-access` | Query the Intuition GraphQL API |
|
|
54
|
+
| `endowment:rpc` | Communicate with dapps |
|
|
55
|
+
| `snap_manageState` | Cache trusted circle data for performance |
|
|
56
|
+
|
|
57
|
+
## Development
|
|
58
|
+
|
|
59
|
+
### Prerequisites
|
|
60
|
+
|
|
61
|
+
- [MetaMask Flask](https://docs.metamask.io/snaps/get-started/install-flask) (development version of MetaMask)
|
|
62
|
+
- Node.js ≥ 18.6.0
|
|
63
|
+
- Yarn
|
|
64
|
+
|
|
65
|
+
### Setup
|
|
66
|
+
|
|
67
|
+
1. Clone the repository:
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/hivemindhq-io/snap.git
|
|
70
|
+
cd intuition-snap
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
2. Install dependencies:
|
|
74
|
+
```bash
|
|
75
|
+
yarn install
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
3. Start the development server:
|
|
79
|
+
```bash
|
|
80
|
+
yarn start
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
4. Open `http://localhost:8000` and connect the Snap to MetaMask Flask
|
|
84
|
+
|
|
85
|
+
### Chain Configuration
|
|
86
|
+
|
|
87
|
+
By default, the Snap connects to **Intuition Testnet**. To use mainnet:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
yarn start:mainnet
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Or explicitly specify testnet:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
yarn start:testnet
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Testing
|
|
100
|
+
|
|
101
|
+
### Automated Tests
|
|
102
|
+
|
|
103
|
+
Run the test suite:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
yarn test
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Tests use [`@metamask/snaps-jest`](https://github.com/MetaMask/snaps/tree/main/packages/snaps-jest) for Snap-specific testing utilities.
|
|
110
|
+
|
|
111
|
+
**What's tested:**
|
|
112
|
+
- `onHomePage` handler — Renders correctly with expected content
|
|
113
|
+
- `Account.tsx` components — All UI rendering variations (26 tests)
|
|
114
|
+
|
|
115
|
+
### Manual E2E Testing
|
|
116
|
+
|
|
117
|
+
The `onTransaction` handler requires network access to the Intuition GraphQL API. Because `@metamask/snaps-jest` runs the Snap in an isolated worker process, network requests cannot be mocked from the test process.
|
|
118
|
+
|
|
119
|
+
**To test transaction insights:**
|
|
120
|
+
|
|
121
|
+
1. Start the development server: `yarn start`
|
|
122
|
+
2. Open http://localhost:8000 in a browser with MetaMask Flask
|
|
123
|
+
3. Install the Snap
|
|
124
|
+
4. Initiate a transaction on Intuition Testnet/Mainnet
|
|
125
|
+
5. Verify trust data displays correctly in the transaction confirmation
|
|
126
|
+
|
|
127
|
+
## Architecture
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
src/
|
|
131
|
+
├── index.tsx # Entry point, exports handlers
|
|
132
|
+
├── onTransaction.tsx # Transaction insight handler
|
|
133
|
+
├── onUserInput.tsx # User interaction handler
|
|
134
|
+
├── account.tsx # Account (destination) data fetching
|
|
135
|
+
├── origin.tsx # dApp origin data fetching
|
|
136
|
+
├── distribution.ts # Stake distribution analysis
|
|
137
|
+
├── queries.ts # GraphQL queries for Intuition API
|
|
138
|
+
├── config.ts # Chain configuration (testnet/mainnet)
|
|
139
|
+
├── types.ts # TypeScript type definitions
|
|
140
|
+
├── util.ts # Utility functions
|
|
141
|
+
├── components/ # JSX UI components
|
|
142
|
+
│ ├── Account.tsx # Destination address display
|
|
143
|
+
│ ├── Origin.tsx # dApp origin display
|
|
144
|
+
│ ├── TrustedCircle.tsx # Trusted contacts display
|
|
145
|
+
│ ├── UnifiedFooter.tsx # Combined footer CTAs
|
|
146
|
+
│ ├── Footer/ # Account footer actions
|
|
147
|
+
│ └── OriginFooter/ # Origin footer actions
|
|
148
|
+
├── trusted-circle/ # Trusted circle module
|
|
149
|
+
│ ├── service.ts # API & business logic
|
|
150
|
+
│ ├── cache.ts # Persistent cache
|
|
151
|
+
│ └── types.ts # Type definitions
|
|
152
|
+
├── images/ # Snap icon assets
|
|
153
|
+
└── vendors/ # Vendor configuration (git-ignored)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Configuration
|
|
157
|
+
|
|
158
|
+
Chain settings are defined in `src/config.ts`:
|
|
159
|
+
|
|
160
|
+
| Network | Chain ID | RPC URL | Currency |
|
|
161
|
+
|---------|----------|---------|----------|
|
|
162
|
+
| Testnet | 13579 | `https://testnet.rpc.intuition.systems` | tTRUST |
|
|
163
|
+
| Mainnet | 1155 | `https://rpc.intuition.systems` | TRUST |
|
|
164
|
+
|
|
165
|
+
### Atoms Used
|
|
166
|
+
|
|
167
|
+
The Snap queries the Intuition knowledge graph using these predefined atoms:
|
|
168
|
+
|
|
169
|
+
| Atom | Purpose |
|
|
170
|
+
|------|---------|
|
|
171
|
+
| `hasTag` | Predicate for trust triples |
|
|
172
|
+
| `trustworthy` | The "trustworthy" characteristic |
|
|
173
|
+
| `hasAlias` | Predicate for alias relationships |
|
|
174
|
+
|
|
175
|
+
## Building
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# Build the snap bundle
|
|
179
|
+
yarn build
|
|
180
|
+
|
|
181
|
+
# Clean and rebuild
|
|
182
|
+
yarn build:clean
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The built bundle is output to `dist/bundle.js`.
|
|
186
|
+
|
|
187
|
+
## Linting
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Run all linters
|
|
191
|
+
yarn lint
|
|
192
|
+
|
|
193
|
+
# Fix auto-fixable issues
|
|
194
|
+
yarn lint:fix
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Contributing
|
|
198
|
+
|
|
199
|
+
1. Fork the repository
|
|
200
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
201
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
202
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
203
|
+
5. Open a Pull Request
|
|
204
|
+
|
|
205
|
+
Please ensure:
|
|
206
|
+
- All tests pass (`yarn test`)
|
|
207
|
+
- Code passes linting (`yarn lint`)
|
|
208
|
+
- No `console.*` statements in production code
|
|
209
|
+
|
|
210
|
+
## License
|
|
211
|
+
|
|
212
|
+
This project is dual-licensed under [Apache 2.0](../../LICENSE.APACHE2) and [MIT](../../LICENSE.MIT0).
|
|
213
|
+
|
|
214
|
+
## Links
|
|
215
|
+
|
|
216
|
+
- [Intuition Documentation](https://docs.intuition.systems)
|
|
217
|
+
- [MetaMask Snaps Documentation](https://docs.metamask.io/snaps/)
|
|
218
|
+
- [Repository](https://github.com/hivemindhq-io/snap)
|
package/dist/bundle.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};function n(t,e,n){if("string"==typeof t)throw new Error(`An HTML element ("${String(t)}") was used in a Snap component, which is not supported by Snaps UI. Please use one of the supported Snap components.`);if(!t)throw new Error("A JSX fragment was used in a Snap component, which is not supported by Snaps UI. Please use one of the supported Snap components.");return t({...e,key:n})}function r(t,e,r){return n(t,e,r)}function i(t){return Object.fromEntries(Object.entries(t).filter((([,t])=>void 0!==t)))}function o(t){return e=>{const{key:n=null,...r}=e;return{type:t,props:i(r),key:n}}}t.r(e),t.d(e,{onHomePage:()=>mt,onTransaction:()=>pt,onUserInput:()=>ht});const a=o("Box"),s=o("Heading"),l=o("Text"),c=o("Divider"),d=o("Link"),u={backendUrl:"https://mainnet.intuition.sh/v1/graphql",rpcUrl:"https://rpc.intuition.systems",chainId:1155,chainIdHex:"0x483",chainName:"Intuition Mainnet",chainKey:"intuition-mainnet",currencySymbol:"TRUST",decimalPrecision:18,hasTagAtomId:"0x6de69cc0ae3efe4000279b1bf365065096c8715d8180bc2a98046ee07d3356fd",trustworthyAtomId:"0xe9c0e287737685382bd34d51090148935bdb671c98d20180b2fec15bd263f73a",hasAliasAtomId:"0xf8cfb4e3f1db08f72f255cf7afaceb4b32684a64dac0f423cdca04dd15cf4fd6"},p=u,h=async(t,e)=>{const n=await fetch(p.backendUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:t,variables:e})});if(!n.ok)throw new Error(`GraphQL request failed: ${n.status} ${n.statusText}`);const r=await n.json();if(r.errors&&r.errors.length>0)throw new Error(`GraphQL error: ${r.errors[0].message}`);return r},m='\nquery TripleWithPositionAggregates($subjectId: String!, $predicateId: String!, $objectId: String!) {\n triples(where: {\n subject_id: { _eq: $subjectId },\n predicate_id: { _eq: $predicateId },\n object_id: { _eq: $objectId }\n }) {\n term_id\n subject_id\n predicate_id\n object_id\n creator_id\n counter_term_id\n\n # Main vault (support) market data\n term {\n vaults(where: { curve_id: { _eq: "1" } }) {\n term_id\n market_cap\n position_count\n curve_id\n }\n }\n\n # Counter vault (oppose) market data\n counter_term {\n vaults(where: { curve_id: { _eq: "1" } }) {\n term_id\n market_cap\n position_count\n curve_id\n }\n }\n\n # Triple-specific aggregated market data\n triple_term {\n term_id\n counter_term_id\n total_market_cap\n total_position_count\n }\n\n # Detailed triple vault data per curve\n triple_vault {\n term_id\n counter_term_id\n curve_id\n position_count\n market_cap\n }\n\n positions_aggregate {\n aggregate {\n count\n sum {\n shares\n }\n avg {\n shares\n }\n }\n }\n\n counter_positions_aggregate {\n aggregate {\n count\n sum {\n shares\n }\n avg {\n shares\n }\n }\n }\n\n positions(\n order_by: { shares: desc }\n limit: 30\n ) {\n id\n account_id\n term_id\n curve_id\n shares\n account {\n id\n label\n }\n }\n\n counter_positions(\n order_by: { shares: desc }\n limit: 30\n ) {\n id\n account_id\n term_id\n curve_id\n shares\n account {\n id\n label\n }\n }\n }\n chainlink_prices(limit: 1, order_by: { id: desc }) {\n usd\n }\n backup_chainlink_prices: chainlink_prices(\n limit: 1,\n order_by: { id: desc },\n where: { usd: { _is_null: false } }\n ) {\n usd\n }\n}\n',g="\nquery OriginAtom($originUrl: String!) {\n atoms(where: {\n _or: [\n { label: { _ilike: $originUrl } },\n { data: { _ilike: $originUrl } }\n ]\n }, limit: 1) {\n term_id\n type\n label\n image\n data\n emoji\n creator_id\n }\n}\n",_="\nquery UserTrustedCircle($userAddress: String!, $predicateId: String!, $objectId: String!) {\n positions(\n where: {\n account_id: { _ilike: $userAddress },\n triple: {\n predicate_id: { _eq: $predicateId },\n object_id: { _eq: $objectId }\n }\n },\n order_by: { shares: desc },\n limit: 200\n ) {\n triple {\n subject_id\n subject {\n label\n }\n }\n }\n}\n";var f,b;!function(t){t.NoAtom="NoAtom",t.AtomWithoutTrustTriple="AtomWithoutTrustTriple",t.AtomWithTrustTriple="AtomWithTrustTriple"}(f||(f={})),function(t){t.NoOrigin="NoOrigin",t.NoAtom="OriginNoAtom",t.AtomWithoutTrustTriple="OriginAtomWithoutTrustTriple",t.AtomWithTrustTriple="OriginAtomWithTrustTriple"}(b||(b={}));const v=(t,e)=>`caip10:${e}:${t}`,w=(t,e)=>{const n=BigInt(t),r=BigInt(10**e),i=n/r,o=(n%r).toString().padStart(e,"0").slice(0,6);return Number(`${i}.${o}`)},y=o("Section"),T=o("Row"),A=o("Address"),I=o("Bold"),C=o("Value"),S={"well-distributed":"success",moderate:"warning",concentrated:"warning","whale-dominated":"warning"},k={"well-distributed":"#22c55e",moderate:"#eab308",concentrated:"#f97316","whale-dominated":"#ef4444"},$={"well-distributed":"Well Distributed",moderate:"Moderate",concentrated:"Concentrated","whale-dominated":"Whale Dominated"},j={"well-distributed":"🟢 Distributed",moderate:"🟡 Moderate",concentrated:"⚠️ Concentrated","whale-dominated":"⛔️ Whale"};function P(t,e){const n=t.filter((t=>t>0));if(0===n.length)return 0;const r=n.reduce(((t,e)=>t+e),0);if(0===r)return 0;return[...n].sort(((t,e)=>e-t)).slice(0,e).reduce(((t,e)=>t+e),0)/r*100}const W={gini:{wellDistributed:.35,moderate:.55,concentrated:.75},top1:{wellDistributed:30,moderate:50,concentrated:80},minStakersForAnalysis:3};function N(t,e,n){const{gini:r,top1:i,minStakersForAnalysis:o}=W;return e>=i.concentrated?"whale-dominated":n<o?e>=i.moderate?"concentrated":0===n?"well-distributed":"moderate":t<=r.wellDistributed?"well-distributed":t<=r.moderate?"moderate":t<=r.concentrated?"concentrated":"whale-dominated"}function O(t){const e=t.filter((t=>t>0)),n=e.length,r=e.reduce(((t,e)=>t+e),0);if(0===n){const t="well-distributed";return{gini:0,nakamoto:0,top1Percent:0,top3Percent:0,stakerCount:0,totalShares:0,status:t,snapColor:S[t],hexColor:k[t],label:"No Stakes",shortLabel:"None"}}const i=function(t){const e=t.filter((t=>t>0)),n=e.length;if(0===n)return 0;if(1===n)return 0;const r=e.reduce(((t,e)=>t+e),0)/n;if(0===r)return 0;let i=0;for(let t=0;t<n;t++)for(let r=0;r<n;r++){const n=e[t],o=e[r];void 0!==n&&void 0!==o&&(i+=Math.abs(n-o))}const o=i/(2*n*n*r);return Math.max(0,Math.min(1,o))}(e),o=function(t){const e=t.filter((t=>t>0));if(0===e.length)return 0;const n=.51*e.reduce(((t,e)=>t+e),0),r=[...e].sort(((t,e)=>e-t));let i=0;for(let t=0;t<r.length;t++){const e=r[t];if(void 0!==e&&(i+=e,i>=n))return t+1}return r.length}(e),a=P(e,1),s=P(e,3),l=N(i,a,n);return{gini:i,nakamoto:o,top1Percent:a,top3Percent:s,stakerCount:n,totalShares:r,status:l,snapColor:S[l],hexColor:k[l],label:$[l],shortLabel:j[l]}}function x(t){return O(t.map((t=>t.shares)).filter((t=>!isNaN(t)&&t>0)))}function q(t){var e,n;if(!t||0===t.count)return O([]);const{count:r,sum:i,avg:o}=t,a=(null===(e=i)||void 0===e?void 0:e.shares)||0;null===(n=o)||void 0===n||n.shares;if(0===r||0===a)return O([]);let s,l;s=1===r?100:2===r?70:r<=5?100/Math.sqrt(r):Math.max(20,100/Math.pow(r,.7)),l=1===r?0:2===r?.5:r<=5?.6:r<=10?.5:.4;const c=N(l,s,r);return{gini:l,nakamoto:1===r?1:Math.ceil(.3*r),top1Percent:s,top3Percent:Math.min(100,1.3*s),stakerCount:r,totalShares:a,status:c,snapColor:S[c],hexColor:k[c],label:$[c],shortLabel:j[c]}}function U(t,e,n,r,i,o){const{level:a,ratio:s}=function(t,e){const n=t+e;if(0===n)return{level:"no-stakes",ratio:50};const r=t/n*100;return r>=70?{level:"trusted",ratio:r}:r>=30?{level:"mixed",ratio:r}:{level:"untrusted",ratio:r}}(t,e),l=n&&n.length>0?x(n):q(i),c=r&&r.length>0?x(r):q(o),d=function(t,e){const n=["well-distributed","moderate","concentrated","whale-dominated"];return n.indexOf(t)>=n.indexOf(e)?t:e}(l.status,c.status);return{trustLevel:a,trustRatio:s,forDistribution:l,againstDistribution:c,overallDistribution:d,overallSnapColor:S[d]}}function D(t){if(0===t.length)return"";const e=t.slice(0,3).map((t=>function(t){if(/^0x[a-fA-F0-9]{40}$/u.test(t))return`${t.slice(0,6)}...${t.slice(-4)}`;if(t.startsWith("caip10:")){const e=t.split(":"),n=e[e.length-1];if(n&&/^0x[a-fA-F0-9]{40}$/u.test(n))return`${n.slice(0,6)}...${n.slice(-4)}`}return t}(t.label)));if(t.length>3){const n=t.length-3;return`${e.join(", ")} +${n} more`}return e.join(", ")}const L=({forContacts:t,againstContacts:e})=>0===t.length&&0===e.length?null:r(y,{children:[n(s,{size:"sm",children:"Your Trusted Contacts"}),t.length>0&&n(T,{label:"FOR",children:n(l,{color:"success",children:n(I,{children:D(t)})})}),e.length>0&&n(T,{label:"AGAINST",children:n(l,{color:"warning",children:n(I,{children:D(e)})})})]}),M=()=>n(s,{size:"sm",children:"Destination"}),E=t=>t.map((t=>({shares:parseFloat(t.shares)||0}))),F=({alternateTrustData:t,isContract:e})=>{if(!t.hasAlternateTrustData)return null;const r=t.alternateIsCaip?`Also has data as a contract on ${p.chainName}`:"Also has data as an EOA";return n(l,{color:"default",children:r})},R={[f.NoAtom]:t=>{const{address:e,isContract:i,alternateTrustData:o}=t,a=i?"contract":"address";return r(y,{children:[n(M,{}),n(T,{label:"Address",children:n(A,{address:e})}),n(T,{label:"Status",variant:"warning",children:n(l,{color:"warning",children:r(I,{children:["Unknown ",a]})})}),n(l,{color:"default",children:"No community data on Intuition"}),n(F,{alternateTrustData:o,isContract:i})]})},[f.AtomWithoutTrustTriple]:t=>{const{address:e,account:i,alias:o,isContract:a,alternateTrustData:s}=t;return r(y,{children:[n(M,{}),n(T,{label:"Address",children:n(A,{address:e})}),!!o&&n(T,{label:"Alias",children:n(l,{children:n(I,{children:o})})}),n(T,{label:"Status",children:n(l,{color:"default",children:"No trust rating yet"})}),n(l,{color:"default",children:"Known address, awaiting community votes"}),n(F,{alternateTrustData:s,isContract:a})]})},[f.AtomWithTrustTriple]:t=>{var e,i,o,a;const{address:s,triple:c,alias:d,isContract:u,alternateTrustData:h,trustedCircle:m}=t,{counter_term:{vaults:[g]},term:{vaults:[_]},positions:f,counter_positions:b,positions_aggregate:v,counter_positions_aggregate:S}=c,k=(null===(e=_)||void 0===e?void 0:e.market_cap)||"0",$=w(k,18),j=(null===(i=g)||void 0===i?void 0:i.market_cap)||"0",P=w(j,18),{badge:W,color:N}=((t,e)=>{const n=t+e;if(0===n)return{badge:"No Stakes",color:"muted"};const r=t/n*100;return r>=70?{badge:"Trusted",color:"success"}:r>=30?{badge:"Mixed",color:"warning"}:{badge:"Untrusted",color:"warning"}})($,P),O=(t=>{const{forDistribution:e}=t,n=["success","warning","muted","default"].includes(e.snapColor)?e.snapColor:"default";return{label:e.shortLabel,color:n}})(U($,P,E(f),E(b),null===(o=v)||void 0===o?void 0:o.aggregate,null===(a=S)||void 0===a?void 0:a.aggregate));return r(y,{children:[n(M,{}),n(T,{label:"Address",children:n(A,{address:s})}),!!d&&n(T,{label:"Alias",children:n(l,{children:n(I,{children:d})})}),n(T,{label:"Trust",children:n(l,{color:N,children:n(I,{children:W})})}),n(T,{label:"Distribution",children:n(l,{color:O.color,children:n(I,{children:O.label})})}),n(T,{label:`FOR (${f.length})`,children:n(C,{value:`${$.toFixed(2)} ${p.currencySymbol}`,extra:""})}),n(T,{label:`AGAINST (${b.length})`,children:n(C,{value:`${P.toFixed(2)} ${p.currencySymbol}`,extra:""})}),n(F,{alternateTrustData:h,isContract:u}),m?n(L,{forContacts:m.forContacts,againstContacts:m.againstContacts}):null]})}},H={1155:"https://explorer.hivemindhq.io",13579:"https://testnet.explorer.hivemindhq.io"}[p.chainId],V={name:"Hive Mind Explorer",noAtom:t=>{const{address:e,chainId:n,isContract:r}=t,i=r?v(e,n):e,o=new URL("/snap/action",H);return o.searchParams.set("intent","complete_trust_triple"),o.searchParams.set("address",i),o.searchParams.set("chain_id",n),{url:o.toString()}},atomWithoutTrustTriple:t=>{const{account:e}=t;if(!e)throw new Error("atomWithoutTrustTriple: account not found");const{term_id:n}=e,r=new URL("/snap/action",H);return r.searchParams.set("intent","create_trust_triple"),r.searchParams.set("atom_id",n),{url:r.toString()}},atomWithTrustTriple:t=>{const{triple:e}=t;if(!e)throw new Error("atomWithTrustTriple: triple not found");const{term_id:n}=e,r=new URL("/snap/action",H);return r.searchParams.set("intent","stake_trust_triple"),r.searchParams.set("triple_id",n),{url:r.toString()}},viewAtom:t=>{const{account:e}=t;if(!e)throw new Error("viewAtom: account not found");const{term_id:n}=e;return{url:new URL(`/atoms/${n}`,H).toString()}},createAlias:t=>{const{account:e}=t;if(!e)throw new Error("createAlias: account not found");const{term_id:n}=e,r=new URL("/snap/action",H);return r.searchParams.set("intent","create_alias"),r.searchParams.set("subject_id",n),{url:r.toString()}},originAtomWithoutTrustTriple:t=>{const{origin:e}=t;if(!e)throw new Error("originAtomWithoutTrustTriple: origin not found");const{term_id:n}=e,r=new URL("/snap/action",H);return r.searchParams.set("intent","create_trust_triple"),r.searchParams.set("atom_id",n),{url:r.toString()}},originAtomWithTrustTriple:t=>{const{triple:e}=t;if(!e)throw new Error("originAtomWithTrustTriple: triple not found");const{term_id:n}=e,r=new URL("/snap/action",H);return r.searchParams.set("intent","stake_trust_triple"),r.searchParams.set("triple_id",n),{url:r.toString()}},viewOriginAtom:t=>{const{origin:e}=t;if(!e)throw new Error("viewOriginAtom: origin not found");const{term_id:n}=e;return{url:new URL(`/atoms/${n}`,H).toString()}}},B=V,G=({href:t,label:e})=>n(a,{children:n(d,{href:t,children:e})}),J=t=>{if(t.accountType!==f.NoAtom)return null;const{url:e}=B.noAtom(t);return n(G,{href:e,label:"Create trust claim"})},z=t=>{if(t.accountType===f.NoAtom)return null;if(t.accountType===f.AtomWithoutTrustTriple){const{url:e}=B.atomWithoutTrustTriple(t);return n(G,{href:e,label:"Is this address trustworthy? Vote"})}if(t.accountType===f.AtomWithTrustTriple){const{triple:e,userAddress:r}=t;if(!!r&&(e.positions.some((t=>{var e;return(null===(e=t.account_id)||void 0===e?void 0:e.toLowerCase())===r.toLowerCase()}))||e.counter_positions.some((t=>{var e;return(null===(e=t.account_id)||void 0===e?void 0:e.toLowerCase())===r.toLowerCase()}))))return null;const{url:i}=B.atomWithTrustTriple(t);return n(G,{href:i,label:"Is this address trustworthy? Vote"})}return null},K=t=>{if(t.accountType===f.NoAtom)return null;if(t.alias)return null;const{url:e}=B.createAlias(t);return n(G,{href:e,label:"Add alias"})},Q=t=>{if(t.accountType===f.NoAtom)return null;const{url:e}=B.viewAtom(t);return n(G,{href:e,label:"View more about this address"})},X=()=>n(s,{size:"sm",children:"dApp Origin"}),Y=t=>t.map((t=>({shares:parseFloat(t.shares)||0}))),Z={[b.NoOrigin]:t=>null,[b.NoAtom]:t=>{const{hostname:e}=t;return r(y,{children:[n(X,{}),n(T,{label:"From",children:n(l,{children:n(I,{children:e||"Unknown"})})}),n(T,{label:"Status",variant:"warning",children:n(l,{color:"warning",children:n(I,{children:"Unknown dApp"})})}),n(l,{color:"default",children:"No community data. Proceed with caution."})]})},[b.AtomWithoutTrustTriple]:t=>{var e;const{hostname:i,origin:o}=t;return r(y,{children:[n(X,{}),n(T,{label:"From",children:n(l,{children:n(I,{children:i||(null===(e=o)||void 0===e?void 0:e.label)||"Unknown"})})}),n(T,{label:"Status",children:n(l,{color:"default",children:"No trust rating yet"})}),n(l,{color:"default",children:"Known dApp, awaiting community votes"})]})},[b.AtomWithTrustTriple]:t=>{var e,i,o,a,s,c,d,u,h;const{hostname:m,origin:g,triple:_,trustedCircle:f}=t,b=null===(i=_.term)||void 0===i||null===(e=i.vaults)||void 0===e?void 0:e[0],v=null===(a=_.counter_term)||void 0===a||null===(o=a.vaults)||void 0===o?void 0:o[0],A=(null===(s=b)||void 0===s?void 0:s.market_cap)||"0",S=w(A,18),k=(null===(c=v)||void 0===c?void 0:c.market_cap)||"0",$=w(k,18),j=(null===(d=_.positions)||void 0===d?void 0:d.length)||0,P=(null===(u=_.counter_positions)||void 0===u?void 0:u.length)||0,{badge:W,color:N}=((t,e)=>{const n=t+e;if(0===n)return{badge:"No Stakes",color:"muted"};const r=t/n*100;return r>=70?{badge:"Trusted",color:"success"}:r>=30?{badge:"Mixed",color:"warning"}:{badge:"Untrusted",color:"warning"}})(S,$),O=(t=>{const{forDistribution:e}=t,n=["success","warning","muted","default"].includes(e.snapColor)?e.snapColor:"default";return{label:e.shortLabel,color:n}})(U(S,$,Y(_.positions||[]),Y(_.counter_positions||[])));return r(y,{children:[n(X,{}),n(T,{label:"From",children:n(l,{children:n(I,{children:m||(null===(h=g)||void 0===h?void 0:h.label)||"Unknown"})})}),n(T,{label:"Trust",children:n(l,{color:N,children:n(I,{children:W})})}),n(T,{label:"Distribution",children:n(l,{color:O.color,children:n(I,{children:O.label})})}),n(T,{label:`FOR (${j})`,children:n(C,{value:`${S.toFixed(2)} ${p.currencySymbol}`,extra:""})}),n(T,{label:`AGAINST (${P})`,children:n(C,{value:`${$.toFixed(2)} ${p.currencySymbol}`,extra:""})}),f?n(L,{forContacts:f.forContacts,againstContacts:f.againstContacts}):null]})}},tt=t=>{if(t.originType===b.NoOrigin||t.originType===b.NoAtom)return null;if(t.originType===b.AtomWithoutTrustTriple){const{url:e}=B.originAtomWithoutTrustTriple(t);return n(G,{href:e,label:"Is this dApp trustworthy? Vote"})}if(t.originType===b.AtomWithTrustTriple){const{url:e}=B.originAtomWithTrustTriple(t);return n(G,{href:e,label:"Is this dApp trustworthy? Vote"})}return null},et=t=>{if(t.originType===b.NoOrigin||t.originType===b.NoAtom)return null;const{url:e}=B.viewOriginAtom(t);return n(G,{href:e,label:"View more about this dApp"})},nt=({accountProps:t,originProps:e})=>{const i=e.originType===b.AtomWithoutTrustTriple||e.originType===b.AtomWithTrustTriple;return r(a,{children:[n(c,{}),r(a,{children:[n(J,{...t}),n(z,{...t}),n(K,{...t}),n(Q,{...t}),i&&n(tt,{...e}),i&&n(et,{...e})]})]})},rt=t=>{var e,n,r,i,o,a;if(!t)return 0n;return BigInt((null===(r=t.term)||void 0===r||null===(n=r.vaults)||void 0===n||null===(e=n[0])||void 0===e?void 0:e.market_cap)??"0")+BigInt((null===(a=t.counter_term)||void 0===a||null===(o=a.vaults)||void 0===o||null===(i=o[0])||void 0===i?void 0:i.market_cap)??"0")},it=async(t,e)=>{const{to:n,data:r}=t,i=v(n,e),o=await(async(t,e)=>{if("0x"!==e)return{type:"contract",certainty:"definite"};try{const e=await fetch(p.rpcUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",method:"eth_getCode",params:[t,"latest"],id:1})});if(!e.ok)return{type:"unknown",certainty:"uncertain",reason:"eth_getCode_failed"};const n=(await e.json()).result;return"0x"===n||null===n?{type:"eoa",certainty:"definite"}:{type:"contract",certainty:"definite"}}catch(t){return{type:"unknown",certainty:"uncertain",reason:"eth_getCode_failed"}}})(n,r),a="contract"===o.type||"uncertain"===o.certainty;try{var s,l,c;const[t]=await Promise.all([h("\nquery AddressAtoms($plainAddress: String!, $caipAddress: String!) {\n # Atoms matching plain address format (for EOAs)\n plainAtoms: atoms(where: {\n _or: [\n { label: { _ilike: $plainAddress } },\n { data: { _ilike: $plainAddress } }\n ]\n }, limit: 1) {\n term_id\n type\n label\n image\n data\n emoji\n creator_id\n }\n\n # Atoms matching CAIP format (for smart contracts)\n caipAtoms: atoms(where: {\n _or: [\n { label: { _ilike: $caipAddress } },\n { data: { _ilike: $caipAddress } }\n ]\n }, limit: 1) {\n term_id\n type\n label\n image\n data\n emoji\n creator_id\n }\n}\n",{plainAddress:n,caipAddress:i})]),{plainAtoms:e,caipAtoms:r}=t.data,g=null===(s=e)||void 0===s?void 0:s[0],_=null===(l=r)||void 0===l?void 0:l[0];if(!g&&!_)return{account:null,triple:null,isContract:a,alias:null,classification:o,alternateTrustData:{hasAlternateTrustData:!1}};const{hasTagAtomId:f,trustworthyAtomId:b,hasAliasAtomId:v}=p,w=[],y=[];g&&(w.push(h(m,{subjectId:g.term_id,predicateId:f,objectId:b})),y.push("plain")),_&&(w.push(h(m,{subjectId:_.term_id,predicateId:f,objectId:b})),y.push("caip"));const T=await Promise.all(w),A={};y.forEach(((t,e)=>{A[t]=T[e].data.triples[0]||null}));const I=((t,e,n,r,i)=>n||e?n?e?"definite"===t.certainty?"contract"===t.type?{primary:n,primaryTriple:i,alternate:e,alternateTriple:r,usedCaip:!0}:{primary:e,primaryTriple:r,alternate:n,alternateTriple:i,usedCaip:!1}:rt(i)>=rt(r)?{primary:n,primaryTriple:i,alternate:e,alternateTriple:r,usedCaip:!0}:{primary:e,primaryTriple:r,alternate:n,alternateTriple:i,usedCaip:!1}:{primary:n,primaryTriple:i,alternate:null,alternateTriple:null,usedCaip:!0}:{primary:e,primaryTriple:r,alternate:null,alternateTriple:null,usedCaip:!1}:{primary:null,primaryTriple:null,alternate:null,alternateTriple:null,usedCaip:!1})(o,g||null,_||null,A.plain||null,A.caip||null),C=rt(I.alternateTriple),S={hasAlternateTrustData:C>0n,alternateAtomId:null===(c=I.alternate)||void 0===c?void 0:c.term_id,alternateMarketCap:C.toString(),alternateIsCaip:!I.usedCaip};let k=null;if(I.primary){var d,u;const t=await h('\n query GetTriplesWithHighestStake($subjectId: String!, $predicateId: String!) {\n triples(\n where: {\n subject_id: { _eq: $subjectId },\n predicate_id: { _eq: $predicateId }\n },\n order_by: { triple_term: { total_market_cap: desc } }\n ) {\n term_id\n subject_id\n predicate_id\n object_id\n creator_id\n counter_term_id\n\n # Triple-specific aggregated market data (stake information)\n triple_term {\n term_id\n counter_term_id\n total_market_cap\n total_position_count\n }\n\n # Individual vault data\n term {\n vaults(where: { curve_id: { _eq: "1" } }) {\n term_id\n market_cap\n position_count\n curve_id\n }\n }\n\n counter_term {\n vaults(where: { curve_id: { _eq: "1" } }) {\n term_id\n market_cap\n position_count\n curve_id\n }\n }\n\n # Object information for context\n object {\n label\n image\n data\n }\n }\n\n chainlink_prices(limit: 1, order_by: { id: desc }) {\n usd\n }\n }\n',{subjectId:I.primary.term_id,predicateId:v});k=(null===(u=t.data.triples[0])||void 0===u||null===(d=u.object)||void 0===d?void 0:d.label)||null}return{account:I.primary,triple:I.primaryTriple,isContract:a,alias:k,classification:o,alternateTrustData:S}}catch(t){throw t}},ot=async t=>{const e=(t=>{if(t)try{return new URL(t).hostname}catch{var e;return null===(e=t.match(/^(?:https?:\/\/)?([^\/]+)/))||void 0===e?void 0:e[1]}})(t);if(!t||!e)return{origin:null,triple:null,hostname:void 0};try{var n;const i=null===(n=(await h(g,{originUrl:t})).data.atoms)||void 0===n?void 0:n[0];if(!i){var r;const t=null===(r=(await h(g,{originUrl:e})).data.atoms)||void 0===r?void 0:r[0];return t?await at(t,e):{origin:null,triple:null,hostname:e}}return await at(i,e)}catch{return{origin:null,triple:null,hostname:e}}},at=async(t,e)=>{const{hasTagAtomId:n,trustworthyAtomId:r}=p;try{var i;const o=await h('\nquery OriginTrustTriple($subjectId: String!, $predicateId: String!, $objectId: String!) {\n triples(where: {\n subject_id: { _eq: $subjectId },\n predicate_id: { _eq: $predicateId },\n object_id: { _eq: $objectId }\n }) {\n term_id\n\n term {\n vaults(where: { curve_id: { _eq: "1" } }) {\n term_id\n market_cap\n position_count\n }\n }\n\n counter_term {\n vaults(where: { curve_id: { _eq: "1" } }) {\n term_id\n market_cap\n position_count\n }\n }\n\n positions(order_by: { shares: desc }, limit: 30) {\n id\n shares\n account_id\n }\n\n counter_positions(order_by: { shares: desc }, limit: 30) {\n id\n shares\n account_id\n }\n }\n}\n',{subjectId:t.term_id,predicateId:n,objectId:r});return{origin:t,triple:(null===(i=o.data.triples)||void 0===i?void 0:i[0])||null,hostname:e}}catch{return{origin:t,triple:null,hostname:e}}},st=36e5;async function lt(t){try{const n=await snap.request({method:"snap_manageState",params:{operation:"get"}});if(!n)return null;const r=n[t.toLowerCase()];return r?(e=r.timestamp,Date.now()-e<st?r.contacts:null):null}catch{return null}var e}async function ct(t){const e=await lt(t);if(null!==e)return e;const n=await async function(t){var e,n;const{hasTagAtomId:r,trustworthyAtomId:i}=p,o=(null===(n=await h(_,{userAddress:t,predicateId:r,objectId:i}))||void 0===n||null===(e=n.data)||void 0===e?void 0:e.positions)||[],a=new Map;for(const t of o){const{subject_id:e,subject:n}=t.triple;var s;a.has(e)||a.set(e,{accountId:e,label:(null===(s=n)||void 0===s?void 0:s.label)||e})}return Array.from(a.values())}(t);return await async function(t,e){try{const n=await snap.request({method:"snap_manageState",params:{operation:"get"}}),r=t.toLowerCase(),i={contacts:e,timestamp:Date.now()},o={...n||{},[r]:i};await snap.request({method:"snap_manageState",params:{operation:"update",newState:o}})}catch{}}(t,n),n}function dt(t,e,n){const r=new Set(t.map((t=>t.accountId.toLowerCase()))),i=new Map(t.map((t=>[t.accountId.toLowerCase(),t.label]))),o=[];for(const t of e){var a;const e=null===(a=t.account_id)||void 0===a?void 0:a.toLowerCase();var s;if(e&&r.has(e))o.push({accountId:t.account_id,label:i.get(e)||(null===(s=t.account)||void 0===s?void 0:s.label)||ut(t.account_id)})}const l=[];for(const t of n){var c;const e=null===(c=t.account_id)||void 0===c?void 0:c.toLowerCase();var d;if(e&&r.has(e))l.push({accountId:t.account_id,label:i.get(e)||(null===(d=t.account)||void 0===d?void 0:d.label)||ut(t.account_id)})}return{forContacts:o,againstContacts:l}}function ut(t){return!t||t.length<12?t||"Unknown":`${t.slice(0,6)}...${t.slice(-4)}`}const pt=async({transaction:t,chainId:e,transactionOrigin:i})=>{let o;try{var s;o=null===(s=await ethereum.request({method:"eth_accounts"}))||void 0===s?void 0:s[0]}catch(t){}const[l,c,d]=await Promise.all([it(t,e),ot(i),o?ct(o):Promise.resolve([])]),u=(t=>{const{account:e,triple:n}=t;return e?null===n?f.AtomWithoutTrustTriple:f.AtomWithTrustTriple:f.NoAtom})(l),p=((t,e)=>{if(!e)return b.NoOrigin;const{origin:n,triple:r}=t;return n?r?b.AtomWithTrustTriple:b.AtomWithoutTrustTriple:b.NoAtom})(c,i);let h,m;if(d.length>0&&l.triple){h=dt(d,l.triple.positions||[],l.triple.counter_positions||[]),0===h.forContacts.length&&0===h.againstContacts.length&&(h=void 0)}if(d.length>0&&c.triple){m=dt(d,c.triple.positions||[],c.triple.counter_positions||[]),0===m.forContacts.length&&0===m.againstContacts.length&&(m=void 0)}const g={...l,accountType:u,address:t.to,userAddress:o,chainId:e,transactionOrigin:i,trustedCircle:h},_={...c,originType:p,originUrl:i,trustedCircle:m},v=(t=>{const{accountType:e}=t;return R[e](t)})(g),w=(t=>{const{originType:e}=t;return Z[e](t)})(_),y=n(nt,{accountProps:g,originProps:_}),T=r(a,{children:[v,w,y]}),A=(t=>JSON.parse(JSON.stringify(t)))({account:g,origin:_});return{id:await snap.request({method:"snap_createInterface",params:{ui:T,context:A}})}},ht=async t=>{},mt=async()=>({content:r(a,{children:[n(s,{children:"Welcome to Hive Mind, powered by Intuition"}),n(l,{children:"Real-time trust and sentiment insights for every transaction."}),n(c,{}),n(l,{children:"Hive Mind shows you community trust data from the Intuition knowledge graph during transactions."}),r(a,{children:[n(d,{href:"https://hivemindhq.io",children:"Check out Hive Mind's product suite"}),n(d,{href:"https://intuition.systems",children:"Learn about Intuition"})]})]})});var gt=exports;for(var _t in e)gt[_t]=e[_t];e.__esModule&&Object.defineProperty(gt,"__esModule",{value:!0})})();
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hivemindhq/snap",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Real-time trust and sentiment insights for every transaction. Powered by Intuition",
|
|
5
|
+
"contributors": [
|
|
6
|
+
{
|
|
7
|
+
"name": "Kylan Hurt",
|
|
8
|
+
"email": "kylan@hivemindhq.io"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/hivemindhq-io/snap"
|
|
14
|
+
},
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"main": "./dist/bundle.js",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist/",
|
|
19
|
+
"src/images/logo.svg",
|
|
20
|
+
"snap.manifest.json"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"allow-scripts": "yarn workspace root allow-scripts",
|
|
24
|
+
"build": "mm-snap build",
|
|
25
|
+
"build:clean": "yarn clean && yarn build",
|
|
26
|
+
"clean": "rimraf dist",
|
|
27
|
+
"lint": "yarn lint:eslint && yarn lint:misc --check",
|
|
28
|
+
"lint:eslint": "eslint . --cache --ext js,ts",
|
|
29
|
+
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
|
|
30
|
+
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' --ignore-path .gitignore",
|
|
31
|
+
"prepublishOnly": "mm-snap manifest",
|
|
32
|
+
"serve": "mm-snap serve",
|
|
33
|
+
"start": "CHAIN=testnet mm-snap watch",
|
|
34
|
+
"start:mainnet": "CHAIN=mainnet mm-snap watch",
|
|
35
|
+
"start:testnet": "CHAIN=testnet mm-snap watch",
|
|
36
|
+
"test": "jest",
|
|
37
|
+
"test:watch": "jest --watch",
|
|
38
|
+
"test:integration": "jest --testPathPattern=onTransaction.test",
|
|
39
|
+
"test:components": "jest --testPathPattern=components",
|
|
40
|
+
"test:coverage": "jest --coverage"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@metamask/snaps-sdk": "^6.10.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@jest/globals": "^29.5.0",
|
|
47
|
+
"@metamask/auto-changelog": "^3.4.4",
|
|
48
|
+
"@metamask/eslint-config": "^12.2.0",
|
|
49
|
+
"@metamask/eslint-config-jest": "^12.1.0",
|
|
50
|
+
"@metamask/eslint-config-nodejs": "^12.1.0",
|
|
51
|
+
"@metamask/eslint-config-typescript": "^12.1.0",
|
|
52
|
+
"@metamask/snaps-cli": "^6.2.1",
|
|
53
|
+
"@metamask/snaps-jest": "^8.2.0",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^5.42.1",
|
|
55
|
+
"@typescript-eslint/parser": "^5.42.1",
|
|
56
|
+
"eslint": "^8.45.0",
|
|
57
|
+
"eslint-config-prettier": "^8.5.0",
|
|
58
|
+
"eslint-plugin-import": "~2.26.0",
|
|
59
|
+
"eslint-plugin-jest": "^27.1.5",
|
|
60
|
+
"eslint-plugin-jsdoc": "^41.1.2",
|
|
61
|
+
"eslint-plugin-n": "^15.7.0",
|
|
62
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
63
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
64
|
+
"jest": "^29.5.0",
|
|
65
|
+
"prettier": "^2.7.1",
|
|
66
|
+
"prettier-plugin-packagejson": "^2.2.11",
|
|
67
|
+
"rimraf": "^3.0.2",
|
|
68
|
+
"ts-jest": "^29.1.0",
|
|
69
|
+
"typescript": "^4.7.4"
|
|
70
|
+
},
|
|
71
|
+
"packageManager": "yarn@3.2.1",
|
|
72
|
+
"engines": {
|
|
73
|
+
"node": ">=18.6.0"
|
|
74
|
+
},
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public",
|
|
77
|
+
"registry": "https://registry.npmjs.org/"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.1.0",
|
|
3
|
+
"description": "Community trust signals for every transaction, powered by Intuition.",
|
|
4
|
+
"proposedName": "Hive Mind",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/hivemindhq-io/snap"
|
|
8
|
+
},
|
|
9
|
+
"source": {
|
|
10
|
+
"shasum": "vLpQcSb97+LD46+U1u7AofVyrTtWWqWW7z0Uz+07LCQ=",
|
|
11
|
+
"location": {
|
|
12
|
+
"npm": {
|
|
13
|
+
"filePath": "dist/bundle.js",
|
|
14
|
+
"iconPath": "src/images/logo.svg",
|
|
15
|
+
"packageName": "@hivemindhq/snap",
|
|
16
|
+
"registry": "https://registry.npmjs.org/"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"initialPermissions": {
|
|
21
|
+
"endowment:transaction-insight": {
|
|
22
|
+
"allowTransactionOrigin": true
|
|
23
|
+
},
|
|
24
|
+
"endowment:page-home": {},
|
|
25
|
+
"endowment:network-access": {},
|
|
26
|
+
"endowment:rpc": {
|
|
27
|
+
"dapps": true,
|
|
28
|
+
"snaps": false
|
|
29
|
+
},
|
|
30
|
+
"snap_manageState": {}
|
|
31
|
+
},
|
|
32
|
+
"manifestVersion": "0.1"
|
|
33
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" width="29.62148" height="34.33696" viewBox="-4.23164 -4.90528 29.62148 34.33696">
|
|
3
|
+
<g id="Layer_4" data-name="Layer 4">
|
|
4
|
+
<path d="M21.1582,6.1641L10.9077.1514l-.4019-.1514L.0005,6.165l-.0005,12.2197,10.4644,6.1416.231-.0015,10.5132-6.1426-.0503-12.2183ZM19.1802,12.2734l-3.4512,2.1265-3.6367-2.1265,3.6401-2.1582,3.4478,2.1582ZM14.9927,15.7437v3.6025l-3.6646-2.1187-.0117-3.6509,3.6763,2.167ZM9.8115,13.6294v3.6323l-3.645,2.1167v-3.6177l3.645-2.1313ZM6.1665,8.8047v-3.6323l3.645,2.1313v3.6177l-3.645-2.1167ZM14.1499,20.667l-3.5723,2.1304-3.5991-2.0859,3.6021-2.1431,3.5693,2.0986ZM6.979,3.895l3.606-2.1689,3.5654,2.124-3.5728,2.0991-3.5986-2.0542ZM11.3477,10.9214v-3.666l3.645-2.0874v3.6367l-3.645,2.1167ZM9.0654,12.2886l-3.6592,2.1182-3.4312-2.1484,3.4214-2.1421,3.6689,2.1724ZM1.4863,10.7681v-3.7148l3.1772-1.8481v3.5557l-3.1772,2.0073ZM4.6626,19.312l-3.1763-1.8335v-3.7012l3.1699,1.9697.0063,3.5649ZM19.6724,13.7812v3.6973l-3.1768,1.834v-3.5239l3.1768-2.0073ZM19.6724,7.1021v3.666l-3.1768-2.0073v-3.5503l3.1768,1.8916Z" fill="#e59200"/>
|
|
5
|
+
</g>
|
|
6
|
+
</svg>
|
|
7
|
+
|