@opentabs-dev/opentabs-plugin-coinbase 0.0.75 → 0.0.77
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 +51 -133
- package/dist/adapter.iife.js +25 -13
- package/dist/adapter.iife.js.map +3 -3
- package/dist/tools.json +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -1,159 +1,77 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Coinbase
|
|
2
2
|
|
|
3
|
-
OpenTabs plugin for Coinbase
|
|
3
|
+
OpenTabs plugin for Coinbase — gives AI agents access to Coinbase through your authenticated browser session.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
|
+
```bash
|
|
8
|
+
opentabs plugin install coinbase
|
|
7
9
|
```
|
|
8
|
-
coinbase/
|
|
9
|
-
├── package.json # Plugin metadata (name, opentabs field, dependencies)
|
|
10
|
-
├── icon.svg # Optional custom icon (square SVG, max 8KB)
|
|
11
|
-
├── icon-inactive.svg # Optional manual inactive icon override
|
|
12
|
-
├── src/
|
|
13
|
-
│ ├── index.ts # Plugin class (extends OpenTabsPlugin)
|
|
14
|
-
│ └── tools/ # One file per tool (using defineTool)
|
|
15
|
-
│ └── example.ts
|
|
16
|
-
└── dist/ # Build output (generated)
|
|
17
|
-
├── adapter.iife.js # Bundled adapter injected into matching tabs
|
|
18
|
-
└── tools.json # Tool schemas for MCP registration
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Configuration
|
|
22
|
-
|
|
23
|
-
Plugin metadata is defined in `package.json` under the `opentabs` field:
|
|
24
|
-
|
|
25
|
-
```json
|
|
26
|
-
{
|
|
27
|
-
"name": "opentabs-plugin-coinbase",
|
|
28
|
-
"main": "dist/adapter.iife.js",
|
|
29
|
-
"opentabs": {
|
|
30
|
-
"displayName": "Coinbase",
|
|
31
|
-
"description": "OpenTabs plugin for Coinbase",
|
|
32
|
-
"urlPatterns": ["*://*.coinbase.com/*"]
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
- **`main`** — entry point for the bundled adapter IIFE
|
|
38
|
-
- **`opentabs.displayName`** — human-readable name shown in the side panel
|
|
39
|
-
- **`opentabs.description`** — short description of what the plugin does
|
|
40
|
-
- **`opentabs.urlPatterns`** — Chrome match patterns for tabs where the adapter is injected
|
|
41
|
-
|
|
42
|
-
## Custom Icons
|
|
43
10
|
|
|
44
|
-
|
|
11
|
+
Or install globally via npm:
|
|
45
12
|
|
|
46
|
-
```
|
|
47
|
-
coinbase
|
|
48
|
-
├── package.json
|
|
49
|
-
├── icon.svg ← custom icon (optional)
|
|
50
|
-
├── icon-inactive.svg ← manual inactive override (optional, requires icon.svg)
|
|
51
|
-
├── src/
|
|
52
|
-
│ └── ...
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @opentabs-dev/opentabs-plugin-coinbase
|
|
53
15
|
```
|
|
54
16
|
|
|
55
|
-
|
|
17
|
+
## Setup
|
|
56
18
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- If no `icon.svg` is provided, the letter avatar is used automatically
|
|
19
|
+
1. Open [coinbase.com](https://www.coinbase.com/home) in Chrome and log in
|
|
20
|
+
2. Open the OpenTabs side panel — the Coinbase plugin should appear as **ready**
|
|
60
21
|
|
|
61
|
-
|
|
22
|
+
## Tools (17)
|
|
62
23
|
|
|
63
|
-
|
|
64
|
-
- Maximum 8 KB file size
|
|
65
|
-
- No embedded `<image>`, `<script>`, or event handler attributes (`onclick`, etc.)
|
|
66
|
-
- Manual `icon-inactive.svg` must use only achromatic (grayscale) colors
|
|
24
|
+
### Account (1)
|
|
67
25
|
|
|
68
|
-
|
|
26
|
+
| Tool | Description | Type |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `get_current_user` | Get the authenticated user profile | Read |
|
|
69
29
|
|
|
70
|
-
|
|
71
|
-
npm install
|
|
72
|
-
npm run build # tsc && opentabs-plugin build
|
|
73
|
-
npm run dev # watch mode (tsc --watch + opentabs-plugin build --watch)
|
|
74
|
-
npm run type-check # tsc --noEmit
|
|
75
|
-
npm run lint # biome
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Adding Tools
|
|
79
|
-
|
|
80
|
-
Create a new file in `src/tools/` using `defineTool`:
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
import { z } from 'zod';
|
|
84
|
-
import { defineTool } from '@opentabs-dev/plugin-sdk';
|
|
85
|
-
|
|
86
|
-
export const myTool = defineTool({
|
|
87
|
-
name: 'my_tool',
|
|
88
|
-
displayName: 'My Tool',
|
|
89
|
-
description: 'What this tool does',
|
|
90
|
-
icon: 'wrench',
|
|
91
|
-
input: z.object({ /* ... */ }),
|
|
92
|
-
output: z.object({ /* ... */ }),
|
|
93
|
-
handle: async (params) => {
|
|
94
|
-
// Tool implementation runs in the browser tab context
|
|
95
|
-
return { /* ... */ };
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Then register it in `src/index.ts` by adding it to the `tools` array.
|
|
30
|
+
### Portfolio (1)
|
|
101
31
|
|
|
102
|
-
|
|
32
|
+
| Tool | Description | Type |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `list_portfolios` | List all portfolios | Read |
|
|
103
35
|
|
|
104
|
-
|
|
36
|
+
### Assets (5)
|
|
105
37
|
|
|
106
|
-
|
|
107
|
-
|
|
38
|
+
| Tool | Description | Type |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `get_asset_by_uuid` | Get asset details by UUID | Read |
|
|
41
|
+
| `get_asset_by_slug` | Get asset details by URL slug | Read |
|
|
42
|
+
| `get_asset_by_symbol` | Get asset details by ticker symbol | Read |
|
|
43
|
+
| `get_asset_categories` | Get categories for an asset | Read |
|
|
44
|
+
| `get_asset_networks` | Get supported networks for an asset | Read |
|
|
108
45
|
|
|
109
|
-
|
|
110
|
-
const token = getLocalStorage('token');
|
|
46
|
+
### Prices (2)
|
|
111
47
|
|
|
112
|
-
|
|
113
|
-
|
|
48
|
+
| Tool | Description | Type |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `get_asset_price` | Get current price for an asset | Read |
|
|
51
|
+
| `compare_asset_prices` | Compare prices of multiple assets | Write |
|
|
114
52
|
|
|
115
|
-
|
|
116
|
-
const appState = getPageGlobal('__APP_STATE__');
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
**Iframe fallback:** Some apps (e.g., Discord) delete `window.localStorage` after boot. `getLocalStorage` automatically tries a hidden same-origin iframe fallback before returning `null`, so you don't need to handle this case manually.
|
|
53
|
+
### Watchlists (5)
|
|
120
54
|
|
|
121
|
-
|
|
55
|
+
| Tool | Description | Type |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `list_watchlists` | List all watchlists | Read |
|
|
58
|
+
| `create_watchlist` | Create a new watchlist | Write |
|
|
59
|
+
| `delete_watchlist` | Delete a watchlist | Write |
|
|
60
|
+
| `add_watchlist_item` | Add an asset to a watchlist | Write |
|
|
61
|
+
| `remove_watchlist_item` | Remove an asset from a watchlist | Write |
|
|
122
62
|
|
|
123
|
-
|
|
63
|
+
### Alerts (3)
|
|
124
64
|
|
|
125
|
-
|
|
65
|
+
| Tool | Description | Type |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `list_price_alerts` | List all price alerts | Read |
|
|
68
|
+
| `create_price_alert` | Create a price alert for an asset | Write |
|
|
69
|
+
| `delete_price_alert` | Delete a price alert | Write |
|
|
126
70
|
|
|
127
|
-
|
|
128
|
-
// src/schemas/channel.ts
|
|
129
|
-
import { z } from 'zod';
|
|
71
|
+
## How It Works
|
|
130
72
|
|
|
131
|
-
|
|
132
|
-
id: z.string().describe('Channel ID'),
|
|
133
|
-
name: z.string().describe('Channel name'),
|
|
134
|
-
});
|
|
73
|
+
This plugin runs inside your Coinbase tab through the [OpenTabs](https://opentabs.dev) Chrome extension. It uses your existing browser session — no API tokens or OAuth apps required. All operations happen as you, with your permissions.
|
|
135
74
|
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Then import and reuse in your tools:
|
|
140
|
-
|
|
141
|
-
```ts
|
|
142
|
-
// src/tools/list-channels.ts
|
|
143
|
-
import { channelSchema } from '../schemas/channel.js';
|
|
144
|
-
|
|
145
|
-
export const listChannels = defineTool({
|
|
146
|
-
name: 'list_channels',
|
|
147
|
-
displayName: 'List Channels',
|
|
148
|
-
description: 'List all available channels',
|
|
149
|
-
icon: 'list',
|
|
150
|
-
input: z.object({}),
|
|
151
|
-
output: z.object({ channels: z.array(channelSchema) }),
|
|
152
|
-
handle: async () => {
|
|
153
|
-
// ...
|
|
154
|
-
return { channels: [] };
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
```
|
|
75
|
+
## License
|
|
158
76
|
|
|
159
|
-
|
|
77
|
+
MIT
|
package/dist/adapter.iife.js
CHANGED
|
@@ -343,6 +343,8 @@
|
|
|
343
343
|
* (e.g., 'https://github.com'), not a match pattern.
|
|
344
344
|
*/
|
|
345
345
|
homepage;
|
|
346
|
+
/** Typed configuration schema — declares settings that users provide via config.json or the side panel. */
|
|
347
|
+
configSchema;
|
|
346
348
|
};
|
|
347
349
|
|
|
348
350
|
// src/coinbase-api.ts
|
|
@@ -14891,21 +14893,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14891
14893
|
};
|
|
14892
14894
|
var src_default = new CoinbasePlugin();
|
|
14893
14895
|
|
|
14894
|
-
// dist/
|
|
14896
|
+
// dist/_adapter_entry_0972161f-6d6c-4d8f-bc93-e0a78908bff2.ts
|
|
14895
14897
|
if (!globalThis.__openTabs) {
|
|
14896
14898
|
globalThis.__openTabs = {};
|
|
14897
14899
|
} else {
|
|
14898
14900
|
const desc = Object.getOwnPropertyDescriptor(globalThis.__openTabs, "adapters");
|
|
14899
14901
|
if (desc && !desc.writable) {
|
|
14900
|
-
const
|
|
14902
|
+
const ot3 = globalThis.__openTabs;
|
|
14901
14903
|
const newAdaptersObj = {};
|
|
14902
|
-
if (
|
|
14903
|
-
for (const key of Object.keys(
|
|
14904
|
-
const d = Object.getOwnPropertyDescriptor(
|
|
14904
|
+
if (ot3.adapters) {
|
|
14905
|
+
for (const key of Object.keys(ot3.adapters)) {
|
|
14906
|
+
const d = Object.getOwnPropertyDescriptor(ot3.adapters, key);
|
|
14905
14907
|
if (d) Object.defineProperty(newAdaptersObj, key, d);
|
|
14906
14908
|
}
|
|
14907
14909
|
}
|
|
14908
|
-
globalThis.__openTabs = Object.assign({},
|
|
14910
|
+
globalThis.__openTabs = Object.assign({}, ot3, { adapters: newAdaptersObj });
|
|
14909
14911
|
}
|
|
14910
14912
|
}
|
|
14911
14913
|
if (!globalThis.__openTabs.adapters) {
|
|
@@ -14943,6 +14945,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14943
14945
|
}
|
|
14944
14946
|
};
|
|
14945
14947
|
var restoreTransport = setLogTransport ? setLogTransport(logTransport) : void 0;
|
|
14948
|
+
var ot2 = globalThis.__openTabs;
|
|
14949
|
+
ot2._notifyReadinessChanged = () => {
|
|
14950
|
+
try {
|
|
14951
|
+
const nonce = globalThis.__openTabs?._readinessNonce;
|
|
14952
|
+
if (nonce) {
|
|
14953
|
+
window.postMessage({ type: "opentabs:readiness-changed", plugin: "coinbase", nonce }, "*");
|
|
14954
|
+
}
|
|
14955
|
+
} catch {
|
|
14956
|
+
}
|
|
14957
|
+
};
|
|
14946
14958
|
var existing = adapters["coinbase"];
|
|
14947
14959
|
if (existing) {
|
|
14948
14960
|
if (typeof existing.teardown === "function") {
|
|
@@ -14954,7 +14966,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14954
14966
|
}
|
|
14955
14967
|
}
|
|
14956
14968
|
if (!Reflect.deleteProperty(adapters, "coinbase")) {
|
|
14957
|
-
const
|
|
14969
|
+
const ot3 = globalThis.__openTabs;
|
|
14958
14970
|
const newAdapters = {};
|
|
14959
14971
|
for (const key of Object.keys(adapters)) {
|
|
14960
14972
|
if (key !== "coinbase") {
|
|
@@ -14962,7 +14974,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14962
14974
|
if (desc) Object.defineProperty(newAdapters, key, desc);
|
|
14963
14975
|
}
|
|
14964
14976
|
}
|
|
14965
|
-
globalThis.__openTabs = Object.assign({},
|
|
14977
|
+
globalThis.__openTabs = Object.assign({}, ot3, { adapters: newAdapters });
|
|
14966
14978
|
}
|
|
14967
14979
|
var hasLifecycleHooks = typeof src_default.onToolInvocationStart === "function" || typeof src_default.onToolInvocationEnd === "function";
|
|
14968
14980
|
for (const tool of src_default.tools) {
|
|
@@ -15023,12 +15035,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15023
15035
|
}
|
|
15024
15036
|
}
|
|
15025
15037
|
};
|
|
15026
|
-
const
|
|
15027
|
-
if (!
|
|
15038
|
+
const ot3 = globalThis.__openTabs;
|
|
15039
|
+
if (!ot3._navigationInterceptor) {
|
|
15028
15040
|
const origPushState = history.pushState.bind(history);
|
|
15029
15041
|
const origReplaceState = history.replaceState.bind(history);
|
|
15030
15042
|
const callbacks = /* @__PURE__ */ new Map();
|
|
15031
|
-
|
|
15043
|
+
ot3._navigationInterceptor = { callbacks, origPushState, origReplaceState };
|
|
15032
15044
|
history.pushState = function(...args) {
|
|
15033
15045
|
origPushState(...args);
|
|
15034
15046
|
for (const cb of callbacks.values()) {
|
|
@@ -15042,7 +15054,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15042
15054
|
}
|
|
15043
15055
|
};
|
|
15044
15056
|
}
|
|
15045
|
-
const interceptor =
|
|
15057
|
+
const interceptor = ot3._navigationInterceptor;
|
|
15046
15058
|
interceptor.callbacks.set("coinbase", checkUrl);
|
|
15047
15059
|
window.addEventListener("popstate", checkUrl);
|
|
15048
15060
|
window.addEventListener("hashchange", checkUrl);
|
|
@@ -15097,5 +15109,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15097
15109
|
};
|
|
15098
15110
|
delete src_default.onDeactivate;
|
|
15099
15111
|
}
|
|
15100
|
-
})();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["coinbase"]){var a=o.adapters["coinbase"];a.__adapterHash="
|
|
15112
|
+
})();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["coinbase"]){var a=o.adapters["coinbase"];a.__adapterHash="752d95f2cace69d7a3ad935e6f35e9aebcf72e721e8b2451aa37376a00a11304";if(a.tools&&Array.isArray(a.tools)){for(var i=0;i<a.tools.length;i++){Object.freeze(a.tools[i]);}Object.freeze(a.tools);}Object.freeze(a);Object.defineProperty(o.adapters,"coinbase",{value:a,writable:false,configurable:false,enumerable:true});Object.defineProperty(o,"adapters",{value:o.adapters,writable:false,configurable:false});}})();
|
|
15101
15113
|
//# sourceMappingURL=adapter.iife.js.map
|