slashvibe-mcp 0.2.2 → 0.2.4

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.
Files changed (162) hide show
  1. package/README.md +1 -0
  2. package/analytics.js +107 -0
  3. package/config.js +174 -3
  4. package/index.js +163 -34
  5. package/intelligence/index.js +45 -0
  6. package/intelligence/infer.js +316 -0
  7. package/intelligence/interests.js +369 -0
  8. package/intelligence/patterns.js +651 -0
  9. package/intelligence/proactive.js +358 -0
  10. package/intelligence/serendipity.js +306 -0
  11. package/notification-emitter.js +77 -0
  12. package/notify.js +141 -18
  13. package/package.json +14 -6
  14. package/presence.js +5 -1
  15. package/protocol/index.js +88 -1
  16. package/protocol/telegram-commands.js +199 -0
  17. package/store/api.js +469 -29
  18. package/store/index.js +7 -7
  19. package/store/local.js +67 -11
  20. package/store/profiles.js +435 -0
  21. package/store/reservations.js +321 -0
  22. package/store/skills.js +378 -0
  23. package/tools/_actions.js +491 -22
  24. package/tools/_connection-queue.js +257 -0
  25. package/tools/_discovery-enhanced.js +290 -0
  26. package/tools/_discovery.js +439 -0
  27. package/tools/_proactive-discovery.js +301 -0
  28. package/tools/_shared/index.js +64 -0
  29. package/tools/_work-context.js +338 -0
  30. package/tools/_work-context.manual-test.js +199 -0
  31. package/tools/_work-context.test.js +260 -0
  32. package/tools/admin-inbox.js +218 -0
  33. package/tools/agent-treasury.js +288 -0
  34. package/tools/agents.js +122 -0
  35. package/tools/analytics.js +191 -0
  36. package/tools/approve.js +197 -0
  37. package/tools/arcade.js +173 -0
  38. package/tools/artifact-create.js +247 -0
  39. package/tools/artifact-view.js +174 -0
  40. package/tools/artifacts-price.js +107 -0
  41. package/tools/ask-expert.js +160 -0
  42. package/tools/auto-suggest-connections.js +304 -0
  43. package/tools/away.js +68 -0
  44. package/tools/back.js +51 -0
  45. package/tools/become-expert.js +150 -0
  46. package/tools/bootstrap-skills.js +231 -0
  47. package/tools/bridge-dashboard.js +342 -0
  48. package/tools/bridge-health.js +400 -0
  49. package/tools/bridge-live.js +384 -0
  50. package/tools/bridges.js +383 -0
  51. package/tools/broadcast.js +286 -0
  52. package/tools/bye.js +4 -0
  53. package/tools/chat.js +202 -0
  54. package/tools/collaborative-drawing.js +286 -0
  55. package/tools/colorguess.js +281 -0
  56. package/tools/crossword.js +369 -0
  57. package/tools/discover-insights.js +379 -0
  58. package/tools/discover-momentum.js +256 -0
  59. package/tools/discover.js +675 -0
  60. package/tools/discovery-analytics.js +345 -0
  61. package/tools/discovery-auto-suggest.js +275 -0
  62. package/tools/discovery-bootstrap.js +267 -0
  63. package/tools/discovery-daily.js +375 -0
  64. package/tools/discovery-dashboard.js +385 -0
  65. package/tools/discovery-digest.js +314 -0
  66. package/tools/discovery-hub.js +357 -0
  67. package/tools/discovery-insights.js +384 -0
  68. package/tools/discovery-momentum.js +281 -0
  69. package/tools/discovery-monitor.js +319 -0
  70. package/tools/discovery-proactive.js +300 -0
  71. package/tools/dm.js +84 -14
  72. package/tools/draw.js +317 -0
  73. package/tools/drawing.js +310 -0
  74. package/tools/earnings.js +126 -0
  75. package/tools/echo.js +16 -0
  76. package/tools/farcaster.js +307 -0
  77. package/tools/feed.js +215 -0
  78. package/tools/follow.js +224 -0
  79. package/tools/friends.js +192 -0
  80. package/tools/game.js +218 -110
  81. package/tools/games-catalog.js +376 -0
  82. package/tools/games.js +313 -0
  83. package/tools/genesis.js +233 -0
  84. package/tools/gig-browse.js +206 -0
  85. package/tools/gig-complete.js +139 -0
  86. package/tools/guessnumber.js +194 -0
  87. package/tools/hangman.js +129 -0
  88. package/tools/help.js +269 -0
  89. package/tools/idea.js +217 -0
  90. package/tools/inbox.js +291 -25
  91. package/tools/init.js +657 -33
  92. package/tools/insights.js +123 -0
  93. package/tools/invite.js +142 -21
  94. package/tools/l2-bridge.js +272 -0
  95. package/tools/l2-status.js +217 -0
  96. package/tools/l2.js +206 -0
  97. package/tools/migrate.js +156 -0
  98. package/tools/mint.js +377 -0
  99. package/tools/multiplayer-game.js +275 -0
  100. package/tools/multiplayer-tictactoe.js +303 -0
  101. package/tools/mute.js +97 -0
  102. package/tools/notifications.js +415 -0
  103. package/tools/observe.js +200 -0
  104. package/tools/onboarding.js +147 -0
  105. package/tools/open.js +52 -3
  106. package/tools/party-game.js +314 -0
  107. package/tools/plan.js +225 -0
  108. package/tools/presence-agent.js +167 -0
  109. package/tools/profile.js +219 -0
  110. package/tools/proof-of-work.js +139 -0
  111. package/tools/pulse.js +218 -0
  112. package/tools/react.js +4 -0
  113. package/tools/release.js +83 -0
  114. package/tools/report.js +109 -0
  115. package/tools/reputation.js +175 -0
  116. package/tools/request.js +231 -0
  117. package/tools/reservations.js +116 -0
  118. package/tools/reserve.js +111 -0
  119. package/tools/riddle.js +240 -0
  120. package/tools/run-bootstrap.js +69 -0
  121. package/tools/schedule.js +367 -0
  122. package/tools/session.js +420 -0
  123. package/tools/session_price.js +128 -0
  124. package/tools/settings.js +200 -0
  125. package/tools/ship.js +188 -0
  126. package/tools/shipback.js +326 -0
  127. package/tools/skills-analytics.js +349 -0
  128. package/tools/skills-bootstrap.js +301 -0
  129. package/tools/skills-dashboard.js +268 -0
  130. package/tools/skills-exchange.js +342 -0
  131. package/tools/skills.js +380 -0
  132. package/tools/smart-intro.js +353 -0
  133. package/tools/social-inbox.js +326 -69
  134. package/tools/social-post.js +251 -66
  135. package/tools/social-processor.js +445 -0
  136. package/tools/solo-game.js +390 -0
  137. package/tools/start.js +296 -81
  138. package/tools/status.js +53 -6
  139. package/tools/storybuilder.js +331 -0
  140. package/tools/stuck.js +297 -0
  141. package/tools/subscribe.js +148 -0
  142. package/tools/subscriptions.js +134 -0
  143. package/tools/suggest-tags.js +184 -0
  144. package/tools/tag-suggestions.js +257 -0
  145. package/tools/telegram-bot.js +183 -0
  146. package/tools/telegram-setup.js +214 -0
  147. package/tools/tictactoe.js +155 -0
  148. package/tools/tip.js +120 -0
  149. package/tools/token.js +103 -0
  150. package/tools/twentyquestions.js +143 -0
  151. package/tools/update.js +1 -1
  152. package/tools/wallet.js +127 -0
  153. package/tools/watch.js +157 -0
  154. package/tools/webhook-test.js +388 -0
  155. package/tools/who.js +118 -25
  156. package/tools/withdraw.js +145 -0
  157. package/tools/wordassociation.js +247 -0
  158. package/tools/work-summary.js +96 -0
  159. package/tools/workshop-buddy.js +394 -0
  160. package/tools/workshop.js +327 -0
  161. package/version.json +12 -3
  162. package/tools/board.js +0 -130
@@ -0,0 +1,123 @@
1
+ /**
2
+ * vibe insights — View your behavioral patterns
3
+ *
4
+ * Shows accumulated insights about your work, social, and creative patterns.
5
+ * All data is stored locally (~/.vibe/work-patterns.json) and never transmitted.
6
+ */
7
+
8
+ const patterns = require('../intelligence/patterns');
9
+ const { requireInit, header, divider } = require('./_shared');
10
+
11
+ const definition = {
12
+ name: 'vibe_insights',
13
+ description: 'View your accumulated work, social, and creative patterns.',
14
+ inputSchema: {
15
+ type: 'object',
16
+ properties: {
17
+ category: {
18
+ type: 'string',
19
+ enum: ['work', 'social', 'creative', 'all'],
20
+ description: 'Which patterns to show (default: all)'
21
+ }
22
+ }
23
+ }
24
+ };
25
+
26
+ function formatTimeAgo(timestamp) {
27
+ if (!timestamp) return 'unknown';
28
+ const seconds = Math.floor((Date.now() - timestamp) / 1000);
29
+ if (seconds < 60) return 'just now';
30
+ if (seconds < 3600) return Math.floor(seconds / 60) + 'm ago';
31
+ if (seconds < 86400) return Math.floor(seconds / 3600) + 'h ago';
32
+ return Math.floor(seconds / 86400) + 'd ago';
33
+ }
34
+
35
+ async function handler(args) {
36
+ const initCheck = requireInit();
37
+ if (initCheck) return initCheck;
38
+
39
+ const category = args.category || 'all';
40
+ let display = header('Your Patterns');
41
+ display += '\n_Local only_\n\n';
42
+
43
+ const data = patterns.load();
44
+
45
+ if (!patterns.hasEnoughData()) {
46
+ display += '_Not enough data yet — keep vibing!_\n';
47
+ display += '_Sessions: ' + data.sessions.total + '_';
48
+ return { display };
49
+ }
50
+
51
+ // Work patterns
52
+ if (category === 'all' || category === 'work') {
53
+ const rhythm = patterns.getSessionRhythm();
54
+ const peakHours = patterns.getPeakHours();
55
+ const dominantState = patterns.getDominantState();
56
+ const topModules = patterns.getTopModules(3);
57
+
58
+ display += '**Work**\n';
59
+ display += rhythm.totalSessions + ' sessions · ' + rhythm.totalHours + 'h total\n';
60
+ display += 'avg ' + rhythm.averageMinutes + 'm · longest ' + rhythm.longestMinutes + 'm\n';
61
+
62
+ if (peakHours.length > 0) {
63
+ const hours = peakHours.map(h => h.hour + ':00').join(', ');
64
+ display += 'peak: ' + hours + '\n';
65
+ }
66
+
67
+ if (dominantState) {
68
+ display += 'usually: ' + dominantState.state + ' (' + dominantState.percentage + '%)\n';
69
+ }
70
+
71
+ if (topModules.length > 0) {
72
+ const mods = topModules.map(m => m.name).join(', ');
73
+ display += 'focus: ' + mods + '\n';
74
+ }
75
+
76
+ display += '\n';
77
+ }
78
+
79
+ // Social patterns
80
+ if (category === 'all' || category === 'social') {
81
+ const social = patterns.getSocialSummary();
82
+ const topConnections = patterns.getTopConnections(3);
83
+
84
+ display += '**Social**\n';
85
+ display += social.messagesSent + ' sent · ' + social.messagesReceived + ' received\n';
86
+ display += social.uniqueConnections + ' connections\n';
87
+
88
+ if (topConnections.length > 0) {
89
+ const names = topConnections.map(c => '@' + c.handle).join(', ');
90
+ display += 'closest: ' + names + '\n';
91
+ }
92
+
93
+ display += '\n';
94
+ }
95
+
96
+ // Creative patterns
97
+ if (category === 'all' || category === 'creative') {
98
+ const creative = patterns.getCreativeSummary();
99
+ const topDomains = patterns.getTopDomains(3);
100
+ const inspirations = patterns.getInspirations(3);
101
+
102
+ display += '**Creative**\n';
103
+ display += creative.totalShips + ' ships · ' + creative.totalIdeas + ' ideas · ' + creative.totalRiffs + ' riffs\n';
104
+
105
+ if (topDomains.length > 0) {
106
+ const domains = topDomains.map(d => '#' + d.domain).join(' ');
107
+ display += 'domains: ' + domains + '\n';
108
+ }
109
+
110
+ if (inspirations.length > 0) {
111
+ const names = inspirations.map(i => '@' + i.handle).join(', ');
112
+ display += 'inspired by: ' + names + '\n';
113
+ }
114
+
115
+ display += '\n';
116
+ }
117
+
118
+ display += divider() + '_since ' + formatTimeAgo(new Date(data.firstSeen).getTime()) + '_';
119
+
120
+ return { display };
121
+ }
122
+
123
+ module.exports = { definition, handler };
package/tools/invite.js CHANGED
@@ -1,10 +1,14 @@
1
1
  /**
2
- * vibe invite — Generate a shareable invite
2
+ * vibe invite — Generate invite codes and shareable messages
3
3
  *
4
- * Creates a personalized invite message for sharing with friends.
4
+ * Actions:
5
+ * - generate: Create a new invite code
6
+ * - list: See your existing codes
7
+ * - (default): Generate a shareable message with your code
5
8
  */
6
9
 
7
10
  const config = require('../config');
11
+ const store = require('../store');
8
12
  const { requireInit } = require('./_shared');
9
13
 
10
14
  const definition = {
@@ -13,6 +17,10 @@ const definition = {
13
17
  inputSchema: {
14
18
  type: 'object',
15
19
  properties: {
20
+ action: {
21
+ type: 'string',
22
+ description: 'Action: "generate" to create code, "list" to see your codes, or omit for shareable message'
23
+ },
16
24
  name: {
17
25
  type: 'string',
18
26
  description: 'Optional: Friend\'s name for personalized message'
@@ -36,15 +44,118 @@ async function handler(args) {
36
44
  const initCheck = requireInit();
37
45
  if (initCheck) return initCheck;
38
46
 
39
- const { name, format } = args;
47
+ const { action, name, format } = args;
40
48
  const myHandle = config.getHandle();
41
49
 
42
- const url = 'slashvibe.dev';
50
+ // Generate a new invite code
51
+ if (action === 'generate') {
52
+ const result = await store.generateInviteCode(myHandle);
53
+
54
+ if (!result.success) {
55
+ return {
56
+ display: `## Could not generate invite code
57
+
58
+ ${result.error || result.message || 'Unknown error'}
59
+
60
+ ${result.remaining === 0 ? 'Share your existing codes first, or wait for them to be used.' : ''}`
61
+ };
62
+ }
63
+
64
+ return {
65
+ display: `## New Invite Code Generated
66
+
67
+ **${result.code}**
68
+
69
+ Share link: ${result.share_url}
70
+
71
+ Expires: ${result.expires_at}
72
+ Remaining codes: ${result.remaining}
73
+
74
+ _When your friend redeems this code, you'll earn a bonus code._`
75
+ };
76
+ }
77
+
78
+ // List existing codes
79
+ if (action === 'list') {
80
+ const result = await store.getMyInvites(myHandle);
81
+
82
+ if (!result.success) {
83
+ return {
84
+ display: `## Could not fetch invites
85
+
86
+ ${result.error || 'Unknown error'}`
87
+ };
88
+ }
89
+
90
+ if (!result.codes || result.codes.length === 0) {
91
+ return {
92
+ display: `## Your Invite Codes
93
+
94
+ No codes yet. Run \`vibe invite --action generate\` to create one.
95
+
96
+ You can have up to ${result.max_codes} unused codes at a time.`
97
+ };
98
+ }
99
+
100
+ const available = result.codes.filter(c => c.status === 'available');
101
+ const used = result.codes.filter(c => c.status === 'used');
102
+
103
+ let display = `## Your Invite Codes
104
+
105
+ **Available** (${available.length}/${result.max_codes})
106
+ `;
107
+
108
+ if (available.length > 0) {
109
+ for (const code of available) {
110
+ display += `\n- **${code.code}** — ${code.share_url}`;
111
+ }
112
+ } else {
113
+ display += '\n_No available codes. Generate one or wait for existing codes to be used._';
114
+ }
115
+
116
+ if (used.length > 0) {
117
+ display += `\n\n**Used** (${used.length})`;
118
+ for (const code of used) {
119
+ display += `\n- ${code.code} → @${code.used_by} (${code.used_at?.split('T')[0] || 'unknown'})`;
120
+ }
121
+ }
122
+
123
+ if (result.can_generate) {
124
+ display += '\n\n_Run `vibe invite --action generate` to create a new code._';
125
+ }
126
+
127
+ return { display };
128
+ }
129
+
130
+ // Get an available code, or auto-generate one
131
+ let shareCode = null;
132
+ let justGenerated = false;
133
+
134
+ const codesResult = await store.getMyInvites(myHandle);
135
+ if (codesResult.success && codesResult.codes) {
136
+ const available = codesResult.codes.find(c => c.status === 'available');
137
+ if (available) {
138
+ shareCode = available.code;
139
+ }
140
+ }
141
+
142
+ // Auto-generate if no available code and user can generate
143
+ if (!shareCode && codesResult.success && codesResult.can_generate) {
144
+ const genResult = await store.generateInviteCode(myHandle);
145
+ if (genResult.success) {
146
+ shareCode = genResult.code;
147
+ justGenerated = true;
148
+ }
149
+ }
150
+
151
+ const shareUrl = shareCode
152
+ ? `slashvibe.dev/invite/${shareCode}`
153
+ : 'slashvibe.dev';
43
154
 
44
155
  // Just the link
45
156
  if (format === 'link') {
46
157
  return {
47
- display: `**${url}**
158
+ display: `**${shareUrl}**
48
159
 
49
160
  Copy and share this with anyone using Claude Code.`
50
161
  };
@@ -58,38 +169,48 @@ Copy and share this with anyone using Claude Code.`
58
169
 
59
170
  > ${randomMsg}
60
171
  >
61
- > ${url}
172
+ > ${shareUrl}
62
173
 
63
174
  _Copy the above and send it._`
64
175
  };
65
176
  }
66
177
 
67
- // Full personalized message (default)
68
- const greeting = name ? `Hey ${name}!` : 'Hey!';
69
- const fromLine = myHandle ? ` — @${myHandle}` : '';
70
-
71
- return {
72
- display: `## Invite to /vibe
178
+ // Default: Quick copy-ready format
179
+ // If name provided, make it personalized
180
+ if (name) {
181
+ return {
182
+ display: `## Invite for ${name}
73
183
 
74
184
  ---
75
185
 
76
- ${greeting}
186
+ Hey ${name}!
77
187
 
78
- I've been using this thing called /vibe in Claude Code — it's a social layer that lets you see who else is building and message people without leaving your terminal.
188
+ I've been using /vibe in Claude Code — it's a social layer that lets you see who else is building and message people without leaving your terminal.
79
189
 
80
- No app to install really, you just tell Claude:
190
+ Just tell Claude: "go to slashvibe.dev and install /vibe"
81
191
 
82
- "go to slashvibe.dev and install /vibe"
192
+ Then say "let's vibe" to start. I'm @${myHandle} — ping me once you're on!
83
193
 
84
- Then say "let's vibe" to start.
194
+ ---
85
195
 
86
- ${name ? `Hit me up once you're on — I'm @${myHandle}` : `I'm @${myHandle} if you want to ping me.`}${fromLine}
196
+ **${shareUrl}**
87
197
 
88
- ---
198
+ _Copy the link above and send it._`
199
+ };
200
+ }
201
+
202
+ // No name: ultra-short copy-ready format
203
+ const genNote = justGenerated ? ' (just generated)' : '';
204
+ const randomMsg = INVITE_MESSAGES[Math.floor(Math.random() * INVITE_MESSAGES.length)];
205
+
206
+ return {
207
+ display: `## Quick Invite${genNote}
89
208
 
90
- **Shareable link**: ${url}
209
+ > ${randomMsg}
210
+ >
211
+ > **${shareUrl}**
91
212
 
92
- _Copy and send to a friend who uses Claude Code._`
213
+ _Copy and send. ${shareCode ? `Bonus code earned when they join.` : ''}_`
93
214
  };
94
215
  }
95
216
 
@@ -0,0 +1,272 @@
1
+ /**
2
+ * vibe_bridge - Bridge ETH between Base and VIBE L2
3
+ *
4
+ * Move assets to VIBE L2 to mint artifacts and interact with
5
+ * the Shipback economy.
6
+ *
7
+ * Deposit: Base → VIBE L2 (~1 minute)
8
+ * Withdrawal: VIBE L2 → Base (~7 days, or ~1 hour with fast mode)
9
+ *
10
+ * Examples:
11
+ * - "vibe bridge deposit 0.1" - Move 0.1 ETH to VIBE L2
12
+ * - "vibe bridge status" - Check bridge status
13
+ * - "vibe bridge withdraw 0.05" - Move ETH back to Base
14
+ */
15
+
16
+ const fetch = require('node-fetch');
17
+ const config = require('../config');
18
+
19
+ const definition = {
20
+ name: 'vibe_bridge',
21
+ description: 'Bridge ETH between Base and VIBE L2. Deposit to mint artifacts, withdraw to cash out.',
22
+ inputSchema: {
23
+ type: 'object',
24
+ properties: {
25
+ action: {
26
+ type: 'string',
27
+ description: 'Action: deposit, withdraw, status, estimate (default: status)'
28
+ },
29
+ amount: {
30
+ type: 'string',
31
+ description: 'Amount in ETH (e.g., "0.1")'
32
+ },
33
+ tx_hash: {
34
+ type: 'string',
35
+ description: 'Transaction hash to check status'
36
+ }
37
+ }
38
+ }
39
+ };
40
+
41
+ async function handler(args) {
42
+ const { action = 'status', amount, tx_hash } = args;
43
+
44
+ if (!config.isInitialized()) {
45
+ return {
46
+ display: 'Run `vibe init` first to set your identity.'
47
+ };
48
+ }
49
+
50
+ const handle = config.getHandle();
51
+
52
+ try {
53
+ switch (action) {
54
+ case 'status':
55
+ return await getBridgeStatus(handle, tx_hash);
56
+
57
+ case 'deposit':
58
+ return await initiateDeposit(handle, amount);
59
+
60
+ case 'withdraw':
61
+ return await initiateWithdraw(handle, amount);
62
+
63
+ case 'estimate':
64
+ return await estimateGas(amount);
65
+
66
+ default:
67
+ return {
68
+ display: `Unknown action: ${action}\n\nValid actions: deposit, withdraw, status, estimate`
69
+ };
70
+ }
71
+ } catch (error) {
72
+ return {
73
+ display: `❌ Bridge operation failed: ${error.message}`
74
+ };
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Get bridge status
80
+ */
81
+ async function getBridgeStatus(handle, txHash) {
82
+ const formatted = `
83
+ ┌────────────────────────────────────────────────────────────┐
84
+ │ 🌉 VIBE BRIDGE │
85
+ │ Base ←→ VIBE L2 │
86
+ ├────────────────────────────────────────────────────────────┤
87
+ │ │
88
+ │ Deposit (Base → VIBE L2) │
89
+ │ ├─ Time: ~1 minute │
90
+ │ ├─ Supported: ETH, USDC │
91
+ │ └─ Use: Mint artifacts, interact with contracts │
92
+ │ │
93
+ │ Withdrawal (VIBE L2 → Base) │
94
+ │ ├─ Standard: ~7 days (challenge period) │
95
+ │ ├─ Fast: ~1 hour (OP Succinct, coming soon) │
96
+ │ └─ Supported: ETH, USDC │
97
+ │ │
98
+ ├────────────────────────────────────────────────────────────┤
99
+ │ Commands: │
100
+ │ ├─ vibe bridge deposit 0.1 - Deposit 0.1 ETH │
101
+ │ ├─ vibe bridge withdraw 0.1 - Withdraw 0.1 ETH │
102
+ │ ├─ vibe bridge estimate - Estimate gas costs │
103
+ │ └─ vibe bridge status - This screen │
104
+ │ │
105
+ ├────────────────────────────────────────────────────────────┤
106
+ │ Bridge UI: https://bridge.vibe.network │
107
+ │ Explorer: https://explorer.vibe.network │
108
+ └────────────────────────────────────────────────────────────┘
109
+ `.trim();
110
+
111
+ if (txHash) {
112
+ return {
113
+ display: formatted + `\n\n📍 Check your transaction: https://explorer.vibe.network/tx/${txHash}`,
114
+ explorerUrl: `https://explorer.vibe.network/tx/${txHash}`
115
+ };
116
+ }
117
+
118
+ return {
119
+ display: formatted,
120
+ bridgeInfo: {
121
+ depositTime: '~1 minute',
122
+ withdrawTime: '~7 days (standard) / ~1 hour (fast)',
123
+ supportedAssets: ['ETH', 'USDC'],
124
+ bridgeUrl: 'https://bridge.vibe.network',
125
+ explorerUrl: 'https://explorer.vibe.network'
126
+ }
127
+ };
128
+ }
129
+
130
+ /**
131
+ * Initiate deposit (Base → VIBE L2)
132
+ */
133
+ async function initiateDeposit(handle, amount) {
134
+ if (!amount) {
135
+ return {
136
+ display: 'Amount required. Example: vibe bridge deposit 0.1'
137
+ };
138
+ }
139
+
140
+ const amountFloat = parseFloat(amount);
141
+ if (isNaN(amountFloat) || amountFloat <= 0) {
142
+ return {
143
+ display: 'Invalid amount. Must be a positive number.'
144
+ };
145
+ }
146
+
147
+ return {
148
+ display: `🌉 DEPOSIT ${amount} ETH to VIBE L2
149
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
150
+
151
+ Amount: ${amount} ETH
152
+ From: Base
153
+ To: VIBE L2
154
+ Time: ~1 minute
155
+
156
+ To complete this deposit:
157
+
158
+ Option 1: Bridge UI (Recommended)
159
+ Visit https://bridge.vibe.network
160
+ Connect your wallet
161
+ Select "Deposit" and enter ${amount} ETH
162
+
163
+ Option 2: Direct Contract Call
164
+ Contract: StandardBridge on Base
165
+ Function: depositETH
166
+ Gas Limit: ~100,000
167
+
168
+ Note: After depositing, your ETH will be available on
169
+ VIBE L2 within ~1 minute. You can then mint artifacts
170
+ and earn Shipback!`,
171
+ action: 'deposit_guidance',
172
+ amount,
173
+ bridgeUrl: `https://bridge.vibe.network?amount=${amount}&direction=deposit`
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Initiate withdrawal (VIBE L2 → Base)
179
+ */
180
+ async function initiateWithdraw(handle, amount) {
181
+ if (!amount) {
182
+ return {
183
+ display: 'Amount required. Example: vibe bridge withdraw 0.1'
184
+ };
185
+ }
186
+
187
+ const amountFloat = parseFloat(amount);
188
+ if (isNaN(amountFloat) || amountFloat <= 0) {
189
+ return {
190
+ display: 'Invalid amount. Must be a positive number.'
191
+ };
192
+ }
193
+
194
+ return {
195
+ display: `🌉 WITHDRAW ${amount} ETH to Base
196
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
197
+
198
+ Amount: ${amount} ETH
199
+ From: VIBE L2
200
+ To: Base
201
+ Time: ~7 days (standard) or ~1 hour (fast mode)
202
+
203
+ ⚠️ IMPORTANT: Withdrawals have a 7-day challenge period.
204
+ This is standard for OP Stack chains (same as Base, Optimism).
205
+
206
+ Fast withdrawals (~1 hour) will be available with OP Succinct.
207
+
208
+ To complete this withdrawal:
209
+
210
+ 1. Visit https://bridge.vibe.network
211
+ 2. Connect your wallet
212
+ 3. Select "Withdraw" and enter ${amount} ETH
213
+ 4. Submit the transaction on VIBE L2
214
+ 5. Wait for challenge period
215
+ 6. Finalize on Base
216
+
217
+ Alternative: Claim your Shipback earnings instead!
218
+ → vibe shipback balance`,
219
+ action: 'withdraw_guidance',
220
+ amount,
221
+ standardTime: '7 days',
222
+ fastTime: '~1 hour (coming soon)',
223
+ bridgeUrl: `https://bridge.vibe.network?amount=${amount}&direction=withdraw`
224
+ };
225
+ }
226
+
227
+ /**
228
+ * Estimate gas costs
229
+ */
230
+ async function estimateGas(amount) {
231
+ const depositGas = 100000;
232
+ const withdrawGas = 150000;
233
+ const gasPrice = 0.001; // gwei on L2
234
+ const baseGasPrice = 0.5; // gwei on Base
235
+
236
+ const depositCostEth = (depositGas * baseGasPrice) / 1e9;
237
+ const withdrawCostL2 = (withdrawGas * gasPrice) / 1e9;
238
+ const withdrawCostBase = (depositGas * baseGasPrice) / 1e9;
239
+
240
+ return {
241
+ display: `⛽ BRIDGE GAS ESTIMATES
242
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
243
+
244
+ Deposit (Base → VIBE L2):
245
+ Gas: ~${depositGas.toLocaleString()} units
246
+ Cost: ~${depositCostEth.toFixed(6)} ETH
247
+ Note: Paid on Base
248
+
249
+ Withdrawal (VIBE L2 → Base):
250
+ Initiate (on L2): ~${withdrawCostL2.toFixed(8)} ETH
251
+ Finalize (on Base): ~${withdrawCostBase.toFixed(6)} ETH
252
+ Total: ~${(withdrawCostL2 + withdrawCostBase).toFixed(6)} ETH
253
+
254
+ On VIBE L2:
255
+ Gas price: ~${gasPrice} gwei (ultra cheap!)
256
+ Mint cost: ~0.0001 ETH
257
+
258
+ 💡 Tip: VIBE L2 has very low gas fees.
259
+ Deposit once, mint many artifacts cheaply!`,
260
+ estimates: {
261
+ deposit: { gas: depositGas, costEth: depositCostEth },
262
+ withdraw: {
263
+ initiateGas: withdrawGas,
264
+ finalizeCostEth: withdrawCostBase,
265
+ totalCostEth: withdrawCostL2 + withdrawCostBase
266
+ },
267
+ l2GasPrice: gasPrice
268
+ }
269
+ };
270
+ }
271
+
272
+ module.exports = { definition, handler };