@crossmint/openclaw-wallet 0.2.3 → 0.3.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 +16 -7
- package/index.ts +2 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/crossmint/SKILL.md +94 -11
- package/src/amazon-order.test.ts +7 -3
- package/src/api.test.ts +9 -4
- package/src/api.ts +13 -7
- package/src/config.ts +1 -1
- package/src/tools.ts +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Enable the plugin in `~/.openclaw/.openclaw.json5`:
|
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
> **Note:**
|
|
38
|
+
> **Note:** This plugin uses Solana mainnet (production) for real transactions.
|
|
39
39
|
|
|
40
40
|
## Usage
|
|
41
41
|
|
|
@@ -53,7 +53,7 @@ The agent will:
|
|
|
53
53
|
|
|
54
54
|
1. Open the delegation URL in your browser
|
|
55
55
|
2. The web app will:
|
|
56
|
-
- Create a Crossmint smart wallet on Solana
|
|
56
|
+
- Create a Crossmint smart wallet on Solana
|
|
57
57
|
- Add the agent's public key as a delegated signer
|
|
58
58
|
- Show you the **wallet address** and **API key**
|
|
59
59
|
|
|
@@ -98,7 +98,7 @@ Price: 0.05 SOL
|
|
|
98
98
|
Order ID: order_abc123
|
|
99
99
|
Payment: completed
|
|
100
100
|
|
|
101
|
-
Transaction: https://explorer.solana.com/tx/5x
|
|
101
|
+
Transaction: https://explorer.solana.com/tx/5x...
|
|
102
102
|
|
|
103
103
|
Use crossmint_order_status to check delivery status.
|
|
104
104
|
```
|
|
@@ -172,7 +172,7 @@ All steps are handled automatically by the plugin.
|
|
|
172
172
|
┌─────────────────────────────────────────────────────────────┐
|
|
173
173
|
│ Crossmint Smart Wallet │
|
|
174
174
|
├─────────────────────────────────────────────────────────────┤
|
|
175
|
-
│ - Deployed on Solana
|
|
175
|
+
│ - Deployed on Solana │
|
|
176
176
|
│ - Agent's address registered as delegated signer │
|
|
177
177
|
│ - User retains admin control │
|
|
178
178
|
│ - Holds SOL/USDC for purchases and transfers │
|
|
@@ -198,14 +198,14 @@ All steps are handled automatically by the plugin.
|
|
|
198
198
|
- Run `crossmint_configure` with wallet address and API key from the web app
|
|
199
199
|
|
|
200
200
|
**"Failed to get balance" or "Failed to send"**
|
|
201
|
-
- Verify the API key is correct (should start with `
|
|
201
|
+
- Verify the API key is correct (should start with `ck_production_`)
|
|
202
202
|
- Check that the wallet address matches the one shown in the web app
|
|
203
203
|
- Ensure the wallet has sufficient balance
|
|
204
204
|
|
|
205
205
|
**"Insufficient funds" (Amazon purchase)**
|
|
206
206
|
- Check balance with `crossmint_balance`
|
|
207
207
|
- Fund the wallet with more SOL or USDC
|
|
208
|
-
-
|
|
208
|
+
- Fund the wallet with real SOL or USDC on Solana mainnet
|
|
209
209
|
|
|
210
210
|
**"Timeout waiting for transaction to be broadcast"**
|
|
211
211
|
- Check transaction status with `crossmint_tx_status`
|
|
@@ -214,15 +214,24 @@ All steps are handled automatically by the plugin.
|
|
|
214
214
|
## Plugin Management
|
|
215
215
|
|
|
216
216
|
```bash
|
|
217
|
+
# Install the plugin
|
|
218
|
+
openclaw plugins install @crossmint/openclaw-wallet
|
|
219
|
+
|
|
220
|
+
# Upgrade to latest version
|
|
221
|
+
openclaw plugins update @crossmint/openclaw-wallet
|
|
222
|
+
|
|
217
223
|
# List all plugins
|
|
218
224
|
openclaw plugins list
|
|
219
225
|
|
|
220
|
-
# Check plugin info
|
|
226
|
+
# Check plugin info (shows current version)
|
|
221
227
|
openclaw plugins info openclaw-wallet
|
|
222
228
|
|
|
223
229
|
# Enable/disable
|
|
224
230
|
openclaw plugins enable openclaw-wallet
|
|
225
231
|
openclaw plugins disable openclaw-wallet
|
|
232
|
+
|
|
233
|
+
# Uninstall
|
|
234
|
+
openclaw plugins uninstall openclaw-wallet
|
|
226
235
|
```
|
|
227
236
|
|
|
228
237
|
## Supported Currencies
|
package/index.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
createCrossmintBuyTool,
|
|
10
10
|
createCrossmintOrderStatusTool,
|
|
11
11
|
} from "./src/tools.js";
|
|
12
|
-
import { crossmintConfigSchema } from "./src/config.js";
|
|
12
|
+
import { crossmintConfigSchema, ENVIRONMENT } from "./src/config.js";
|
|
13
13
|
|
|
14
14
|
const plugin = {
|
|
15
15
|
id: "openclaw-wallet",
|
|
@@ -64,7 +64,7 @@ const plugin = {
|
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
api.logger.info("Crossmint wallet plugin loaded", {
|
|
67
|
-
environment:
|
|
67
|
+
environment: ENVIRONMENT,
|
|
68
68
|
});
|
|
69
69
|
},
|
|
70
70
|
};
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ metadata: { "openclaw": { "emoji": "💳" } }
|
|
|
8
8
|
|
|
9
9
|
Manage Solana wallets using Crossmint smart wallets with delegated signing. The agent holds a local signing key, and users authorize it via a web-based delegation flow.
|
|
10
10
|
|
|
11
|
-
> **Note:**
|
|
11
|
+
> **Note:** This plugin uses **Solana mainnet** (production) for real transactions.
|
|
12
12
|
|
|
13
13
|
## When to Activate
|
|
14
14
|
|
|
@@ -48,7 +48,7 @@ This generates a local ed25519 keypair and returns a delegation URL pointing to
|
|
|
48
48
|
### Step 2: User completes web setup
|
|
49
49
|
|
|
50
50
|
The user opens the delegation URL in their browser. The web app (lobster.cash) will:
|
|
51
|
-
1. Create a Crossmint smart wallet on Solana
|
|
51
|
+
1. Create a Crossmint smart wallet on Solana
|
|
52
52
|
2. Add the agent's public key as a delegated signer
|
|
53
53
|
3. Display the **wallet address** and **API key** for the user to copy
|
|
54
54
|
|
|
@@ -112,6 +112,42 @@ Agent: Use crossmint_wallet_info
|
|
|
112
112
|
|
|
113
113
|
Buy products from Amazon using SOL or USDC from the agent's wallet. Crossmint acts as Merchant of Record, handling payments, shipping, and taxes.
|
|
114
114
|
|
|
115
|
+
### CRITICAL: Product Validation
|
|
116
|
+
|
|
117
|
+
**ALWAYS validate that the product matches what the user requested before completing a purchase.**
|
|
118
|
+
|
|
119
|
+
When a purchase completes, the response includes the product title. The agent MUST:
|
|
120
|
+
|
|
121
|
+
1. **Compare the product title** with what the user asked for
|
|
122
|
+
2. **If there's a mismatch**, inform the user immediately:
|
|
123
|
+
```
|
|
124
|
+
⚠️ The product found doesn't match your request.
|
|
125
|
+
|
|
126
|
+
You asked for: "Celsius Energy Drink"
|
|
127
|
+
Product found: "USB Cable Organizer"
|
|
128
|
+
|
|
129
|
+
This might be the wrong product. Would you like me to:
|
|
130
|
+
1. Search for the correct product on Amazon
|
|
131
|
+
2. Cancel and try a different ASIN
|
|
132
|
+
3. Proceed anyway (if this is actually correct)
|
|
133
|
+
```
|
|
134
|
+
3. **Never assume** - If the user says "buy Celsius" without an ASIN, search Amazon first to find the correct product
|
|
135
|
+
4. **Confirm before payment** - For vague requests, always confirm the exact product before purchasing
|
|
136
|
+
|
|
137
|
+
**Best Practice Flow:**
|
|
138
|
+
```
|
|
139
|
+
User: "Buy me some Celsius energy drinks"
|
|
140
|
+
Agent:
|
|
141
|
+
1. First, search Amazon for "Celsius energy drink" to find the correct ASIN
|
|
142
|
+
2. Present options: "I found these Celsius products:
|
|
143
|
+
- B08P5H1FLX: Celsius Sparkling Orange (12-pack) - ~$25
|
|
144
|
+
- B07GX3GDN5: Celsius Variety Pack (12-pack) - ~$30
|
|
145
|
+
Which one would you like?"
|
|
146
|
+
3. User confirms: "The variety pack"
|
|
147
|
+
4. Agent uses crossmint_buy with the confirmed ASIN
|
|
148
|
+
5. After purchase, verify the product title in the response matches
|
|
149
|
+
```
|
|
150
|
+
|
|
115
151
|
### How It Works (Under the Hood)
|
|
116
152
|
|
|
117
153
|
When you use `crossmint_buy`, the plugin executes a 6-step delegated signer flow:
|
|
@@ -154,7 +190,7 @@ Price: 0.05 SOL
|
|
|
154
190
|
Order ID: order_abc123
|
|
155
191
|
Payment: completed
|
|
156
192
|
|
|
157
|
-
Transaction: https://explorer.solana.com/tx/5x
|
|
193
|
+
Transaction: https://explorer.solana.com/tx/5x...
|
|
158
194
|
|
|
159
195
|
Shipping to:
|
|
160
196
|
John Doe
|
|
@@ -178,6 +214,26 @@ Returns:
|
|
|
178
214
|
- Delivery status
|
|
179
215
|
- Tracking information (when available)
|
|
180
216
|
|
|
217
|
+
### Finding the Right Product
|
|
218
|
+
|
|
219
|
+
When the user doesn't provide an ASIN:
|
|
220
|
+
|
|
221
|
+
1. **Search Amazon first** - Use web search to find the product: `"[product name] site:amazon.com"`
|
|
222
|
+
2. **Extract the ASIN** - Look for the 10-character alphanumeric code (e.g., B08P5H1FLX) in the URL
|
|
223
|
+
3. **Confirm with user** - Show the product name, price estimate, and ask for confirmation
|
|
224
|
+
4. **Then purchase** - Only call `crossmint_buy` after user confirms the correct product
|
|
225
|
+
|
|
226
|
+
**Example:**
|
|
227
|
+
```
|
|
228
|
+
User: "Buy me Celsius energy drinks"
|
|
229
|
+
Agent: Let me search Amazon for Celsius energy drinks...
|
|
230
|
+
[searches "Celsius energy drink site:amazon.com"]
|
|
231
|
+
I found: "CELSIUS Sparkling Orange Fitness Drink (12-pack)" - ASIN: B08P5H1FLX
|
|
232
|
+
Is this what you want? (Yes/No, or tell me a different product)
|
|
233
|
+
User: "Yes"
|
|
234
|
+
Agent: [calls crossmint_buy with B08P5H1FLX]
|
|
235
|
+
```
|
|
236
|
+
|
|
181
237
|
### Amazon Product Locator Formats
|
|
182
238
|
|
|
183
239
|
All of these formats work:
|
|
@@ -304,7 +360,7 @@ Agent:
|
|
|
304
360
|
|
|
305
361
|
### "Failed to get balance" or "Failed to send"
|
|
306
362
|
|
|
307
|
-
- Verify the API key is correct (should start with `
|
|
363
|
+
- Verify the API key is correct (should start with `ck_production_`)
|
|
308
364
|
- Check wallet address matches the one shown in the web app
|
|
309
365
|
- Ensure sufficient balance for transfers
|
|
310
366
|
|
|
@@ -316,7 +372,31 @@ The wallet doesn't have enough SOL or USDC for the purchase.
|
|
|
316
372
|
Agent:
|
|
317
373
|
1. Use crossmint_balance to check current balance
|
|
318
374
|
2. Ask user to fund the wallet with more SOL/USDC
|
|
319
|
-
3.
|
|
375
|
+
3. Fund the wallet with real SOL/USDC on Solana mainnet
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### "Wrong product was purchased"
|
|
379
|
+
|
|
380
|
+
The product title doesn't match what the user requested.
|
|
381
|
+
|
|
382
|
+
**Prevention:**
|
|
383
|
+
1. Always search for the correct ASIN before purchasing
|
|
384
|
+
2. Confirm the product with the user before calling `crossmint_buy`
|
|
385
|
+
3. After purchase, compare the product title in the response with user's request
|
|
386
|
+
|
|
387
|
+
**If it happens:**
|
|
388
|
+
```
|
|
389
|
+
Agent:
|
|
390
|
+
⚠️ I notice the product purchased doesn't match your request.
|
|
391
|
+
|
|
392
|
+
You asked for: "Celsius Energy Drink"
|
|
393
|
+
Product purchased: "USB Cable Organizer" (Order ID: xxx)
|
|
394
|
+
|
|
395
|
+
Unfortunately, the payment has already been processed. You may need to:
|
|
396
|
+
1. Contact Crossmint support to request a cancellation/refund
|
|
397
|
+
2. Wait for delivery and return the item
|
|
398
|
+
|
|
399
|
+
I apologize for this error. In the future, I'll confirm the exact product with you before purchasing.
|
|
320
400
|
```
|
|
321
401
|
|
|
322
402
|
### "Order created but no serialized transaction returned"
|
|
@@ -348,12 +428,15 @@ Agent:
|
|
|
348
428
|
|
|
349
429
|
## Best Practices
|
|
350
430
|
|
|
351
|
-
1. **
|
|
352
|
-
2. **
|
|
353
|
-
3. **
|
|
354
|
-
4. **
|
|
355
|
-
5. **
|
|
356
|
-
6. **
|
|
431
|
+
1. **ALWAYS validate products before purchasing** - Never buy without confirming the product matches user intent
|
|
432
|
+
2. **Search Amazon first for vague requests** - If user says "buy X" without an ASIN, search for the correct product first
|
|
433
|
+
3. **Confirm product title after purchase** - Check that the returned product title matches what was requested
|
|
434
|
+
4. **Always check balance before purchasing** - Avoid failed transactions due to insufficient funds
|
|
435
|
+
5. **Confirm shipping address with user** - Double-check addresses for Amazon purchases
|
|
436
|
+
6. **Fund wallet before purchasing** - Ensure the wallet has enough SOL or USDC before attempting purchases
|
|
437
|
+
7. **One wallet per agent** - Each agent ID gets its own keypair and wallet
|
|
438
|
+
8. **Save the order ID** - Users should note the order ID to track delivery status later
|
|
439
|
+
9. **Verify on-chain** - The explorer link lets users verify the payment transaction on Solana
|
|
357
440
|
|
|
358
441
|
## Supported Currencies
|
|
359
442
|
|
package/src/amazon-order.test.ts
CHANGED
|
@@ -27,9 +27,13 @@ const API_KEY = process.env.CROSSMINT_API_KEY || "";
|
|
|
27
27
|
const PAYER_ADDRESS = process.env.PAYER_ADDRESS || ""; // Smart wallet address
|
|
28
28
|
const SIGNER_PRIVATE_KEY = process.env.PAYER_PRIVATE_KEY || ""; // Delegated signer private key
|
|
29
29
|
|
|
30
|
-
// Crossmint API base URLs
|
|
31
|
-
const
|
|
32
|
-
const
|
|
30
|
+
// Crossmint API base URLs - depends on environment
|
|
31
|
+
const CROSSMINT_ENV = process.env.CROSSMINT_ENV || "production";
|
|
32
|
+
const CROSSMINT_BASE_URL = CROSSMINT_ENV === "staging"
|
|
33
|
+
? "https://staging.crossmint.com/api"
|
|
34
|
+
: "https://www.crossmint.com/api";
|
|
35
|
+
const CROSSMINT_ORDERS_API = `${CROSSMINT_BASE_URL}/2022-06-09`;
|
|
36
|
+
const CROSSMINT_WALLETS_API = `${CROSSMINT_BASE_URL}/2025-06-09`;
|
|
33
37
|
|
|
34
38
|
// Test product - can be overridden via environment variable
|
|
35
39
|
const TEST_AMAZON_ASIN = process.env.TEST_AMAZON_ASIN || "B00AATAHY0";
|
package/src/api.test.ts
CHANGED
|
@@ -12,13 +12,18 @@ import {
|
|
|
12
12
|
/**
|
|
13
13
|
* Live integration tests for Crossmint Amazon purchase API.
|
|
14
14
|
*
|
|
15
|
-
* Run with: CROSSMINT_API_KEY=your-key pnpm test
|
|
15
|
+
* Run with: CROSSMINT_API_KEY=your-key pnpm test src/api.test.ts
|
|
16
16
|
*
|
|
17
|
-
* These tests make real API calls to Crossmint
|
|
18
|
-
* They require a valid
|
|
17
|
+
* These tests make real API calls to Crossmint.
|
|
18
|
+
* They require a valid API key with orders.create scope.
|
|
19
|
+
*
|
|
20
|
+
* Environment:
|
|
21
|
+
* CROSSMINT_ENV=staging -> Uses devnet (staging.crossmint.com)
|
|
22
|
+
* CROSSMINT_ENV=production (default) -> Uses mainnet (www.crossmint.com)
|
|
19
23
|
*/
|
|
20
24
|
|
|
21
25
|
const LIVE = process.env.CROSSMINT_API_KEY || process.env.LIVE;
|
|
26
|
+
const CROSSMINT_ENV = (process.env.CROSSMINT_ENV || "production") as "staging" | "production";
|
|
22
27
|
|
|
23
28
|
describe("crossmint api", () => {
|
|
24
29
|
describe("buildDelegationUrl", () => {
|
|
@@ -53,7 +58,7 @@ describe("crossmint api", () => {
|
|
|
53
58
|
describe.skipIf(!LIVE)("live: createOrder", () => {
|
|
54
59
|
const config: CrossmintApiConfig = {
|
|
55
60
|
apiKey: process.env.CROSSMINT_API_KEY!,
|
|
56
|
-
environment:
|
|
61
|
+
environment: CROSSMINT_ENV,
|
|
57
62
|
};
|
|
58
63
|
|
|
59
64
|
// Generate a test keypair for the payer address
|
package/src/api.ts
CHANGED
|
@@ -3,7 +3,7 @@ import bs58 from "bs58";
|
|
|
3
3
|
|
|
4
4
|
export type CrossmintApiConfig = {
|
|
5
5
|
apiKey: string;
|
|
6
|
-
environment: "staging"
|
|
6
|
+
environment: "staging" | "production";
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
export type CrossmintBalance = {
|
|
@@ -26,9 +26,10 @@ export type CrossmintTransaction = {
|
|
|
26
26
|
};
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
function getBaseUrl(env: "staging" | "production"): string {
|
|
30
|
+
if (env === "production") {
|
|
31
|
+
return "https://www.crossmint.com/api";
|
|
32
|
+
}
|
|
32
33
|
return "https://staging.crossmint.com/api";
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -106,14 +107,19 @@ export async function getTransactionStatus(
|
|
|
106
107
|
|
|
107
108
|
const data = await response.json();
|
|
108
109
|
|
|
110
|
+
const txId = data.onChain?.txId;
|
|
111
|
+
const explorerLink = txId
|
|
112
|
+
? config.environment === "staging"
|
|
113
|
+
? `https://explorer.solana.com/tx/${txId}?cluster=devnet`
|
|
114
|
+
: `https://explorer.solana.com/tx/${txId}`
|
|
115
|
+
: undefined;
|
|
116
|
+
|
|
109
117
|
return {
|
|
110
118
|
id: data.id,
|
|
111
119
|
status: data.status,
|
|
112
120
|
hash: data.onChain?.txId || data.hash,
|
|
113
121
|
txId: data.txId, // Top-level txId from API response
|
|
114
|
-
explorerLink
|
|
115
|
-
? `https://explorer.solana.com/tx/${data.onChain.txId}?cluster=devnet`
|
|
116
|
-
: undefined,
|
|
122
|
+
explorerLink,
|
|
117
123
|
onChain: data.onChain,
|
|
118
124
|
};
|
|
119
125
|
}
|
package/src/config.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Hardcoded configuration - no user config needed
|
|
2
2
|
export const DELEGATION_URL = "https://www.lobster.cash/";
|
|
3
|
-
export const ENVIRONMENT = "
|
|
3
|
+
export const ENVIRONMENT = "production" as const;
|
|
4
4
|
|
|
5
5
|
export type CrossmintPluginConfig = Record<string, never>;
|
|
6
6
|
|
package/src/tools.ts
CHANGED
|
@@ -26,7 +26,7 @@ function getAgentId(ctx: OpenClawPluginToolContext): string {
|
|
|
26
26
|
return ctx.agentId || "main";
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function getApiConfig(walletData: { apiKey?: string }, environment: "staging"): CrossmintApiConfig {
|
|
29
|
+
function getApiConfig(walletData: { apiKey?: string }, environment: "staging" | "production"): CrossmintApiConfig {
|
|
30
30
|
if (!walletData.apiKey) {
|
|
31
31
|
throw new Error("Wallet not configured. Run crossmint_setup first and provide the API key.");
|
|
32
32
|
}
|