mint-day 0.3.3 → 0.4.1
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/.github/workflows/sentry-triage.yml +69 -0
- package/api/classify.ts +2 -0
- package/api/feed.ts +2 -0
- package/api/lib/sentry.ts +28 -0
- package/api/sentry-webhook.ts +91 -0
- package/api/sponsor.ts +2 -0
- package/api/verify.ts +2 -0
- package/dist/index.js +4 -4
- package/dist/services/rare-protocol.d.ts +19 -0
- package/dist/services/rare-protocol.js +77 -0
- package/dist/tools/mint.d.ts +5 -0
- package/dist/tools/mint.js +48 -10
- package/package.json +4 -1
- package/scripts/deploy-rare-collection.mjs +64 -0
- package/site/feed.html +442 -279
- package/site/index.html +40 -7
- package/src/index.ts +4 -4
- package/src/rare-cli.d.ts +37 -0
- package/src/services/rare-protocol.ts +119 -0
- package/src/tools/mint.ts +50 -11
- package/vercel.json +2 -1
package/site/index.html
CHANGED
|
@@ -374,12 +374,18 @@
|
|
|
374
374
|
<!-- ── Hero ── -->
|
|
375
375
|
<section class="hero">
|
|
376
376
|
<h1>Free <span class="green">NFT minting</span> for agents. On Base.</h1>
|
|
377
|
-
<p class="subtitle">No wallet. No gas. No code.
|
|
378
|
-
<div
|
|
379
|
-
<div
|
|
380
|
-
<
|
|
381
|
-
<
|
|
377
|
+
<p class="subtitle">No wallet. No gas. No code. Describe what to mint — identity, credentials, art — and it lands on Base in seconds. <strong>Works for humans too.</strong></p>
|
|
378
|
+
<div style="margin-top:32px;margin-bottom:24px;font-family:'JetBrains Mono',monospace;font-size:14px;color:var(--text-secondary);display:flex;flex-direction:column;gap:12px;">
|
|
379
|
+
<div style="display:flex;align-items:center;gap:12px;">
|
|
380
|
+
<span style="width:20px;height:20px;border-radius:50%;background:var(--surface-raised);border:1px solid var(--border-bright);display:inline-flex;align-items:center;justify-content:center;font-size:11px;color:var(--text-dim);flex-shrink:0;">1</span>
|
|
381
|
+
<span>Add mint.day to your agent</span>
|
|
382
|
+
</div>
|
|
383
|
+
<div style="display:flex;align-items:center;gap:12px;">
|
|
384
|
+
<span style="width:20px;height:20px;border-radius:50%;background:var(--surface-raised);border:1px solid var(--border-bright);display:inline-flex;align-items:center;justify-content:center;font-size:11px;color:var(--text-dim);flex-shrink:0;">2</span>
|
|
385
|
+
<span>Tell it what to mint — it lands on Base</span>
|
|
382
386
|
</div>
|
|
387
|
+
</div>
|
|
388
|
+
<div class="install-row hero-install">
|
|
383
389
|
<button class="copy-setup-btn" onclick="copySetup(this)"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:6px"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>Copy setup for your agent</button>
|
|
384
390
|
<a href="https://github.com/jordanlyall/mintday" target="_blank" class="github-btn"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>Docs & Source</a>
|
|
385
391
|
</div>
|
|
@@ -479,6 +485,29 @@
|
|
|
479
485
|
</div>
|
|
480
486
|
</section>
|
|
481
487
|
|
|
488
|
+
<!-- ── Protocols ── -->
|
|
489
|
+
<section class="usecases" style="margin-top:64px;">
|
|
490
|
+
<div class="section-label">Two protocols, one tool</div>
|
|
491
|
+
<div class="usecase-grid" style="grid-template-columns:1fr 1fr;">
|
|
492
|
+
<div class="usecase">
|
|
493
|
+
<div style="font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:600;color:var(--text);margin-bottom:8px;">mint.day</div>
|
|
494
|
+
<div class="usecase-scenario">Gas-sponsored minting on the MintFactory contract. Free, zero config. Best for identity, credentials, attestations, and utility tokens.</div>
|
|
495
|
+
<div style="margin-top:12px;font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text-dim);">
|
|
496
|
+
<div>platform: <span style="color:var(--green);">"mintday"</span> <span style="opacity:0.5;">(default)</span></div>
|
|
497
|
+
<div style="margin-top:4px;">gas: sponsored</div>
|
|
498
|
+
</div>
|
|
499
|
+
</div>
|
|
500
|
+
<div class="usecase">
|
|
501
|
+
<div style="font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:600;color:var(--text);margin-bottom:8px;">Rare Protocol <span style="font-weight:400;color:var(--text-dim);font-size:11px;">(SuperRare)</span></div>
|
|
502
|
+
<div class="usecase-scenario">Mint on Rare Protocol ERC-721 contracts on Base. Permissionless. Best for art, collectibles, and visual tokens that belong on SuperRare.</div>
|
|
503
|
+
<div style="margin-top:12px;font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text-dim);">
|
|
504
|
+
<div>platform: <span style="color:var(--green);">"superrare"</span></div>
|
|
505
|
+
<div style="margin-top:4px;">gas: bring your own key</div>
|
|
506
|
+
</div>
|
|
507
|
+
</div>
|
|
508
|
+
</div>
|
|
509
|
+
</section>
|
|
510
|
+
|
|
482
511
|
<!-- ── FAQ ── -->
|
|
483
512
|
<section class="faq" id="faq">
|
|
484
513
|
<div class="section-label">FAQ</div>
|
|
@@ -507,8 +536,12 @@
|
|
|
507
536
|
<div class="faq-a">Yes. Pass an image URL or a local file path. Local files are auto-uploaded and pinned. PFPs, art, screenshots, generated visuals. If your agent can see it, it can mint it.</div>
|
|
508
537
|
</div>
|
|
509
538
|
<div class="faq-item">
|
|
510
|
-
<div class="faq-q">
|
|
511
|
-
<div class="faq-a"
|
|
539
|
+
<div class="faq-q">Can I mint on SuperRare / Rare Protocol?</div>
|
|
540
|
+
<div class="faq-a">Yes. Set <code>platform: "superrare"</code> in your mint call. Tokens mint on Rare Protocol ERC-721 contracts on Base. Requires a private key (no sponsored gas for this path). Set <code>RARE_CONTRACT</code> to your collection address, or deploy one with <code>node scripts/deploy-rare-collection.mjs</code>.</div>
|
|
541
|
+
</div>
|
|
542
|
+
<div class="faq-item">
|
|
543
|
+
<div class="faq-q">Where are the contracts?</div>
|
|
544
|
+
<div class="faq-a">MintFactory: <a href="https://basescan.org/address/0x12a1c11a0b2860f64e7d8df20989f97d40de7f2c" target="_blank">0x12a1...7f2c</a>. Rare Protocol collection: <a href="https://basescan.org/address/0x99Eee317921a9f12176eED25b0aE1D7eb164AE34" target="_blank">0x99Ee...AE34</a>. Both on Base mainnet.</div>
|
|
512
545
|
</div>
|
|
513
546
|
</section>
|
|
514
547
|
|
package/src/index.ts
CHANGED
|
@@ -14,11 +14,11 @@ import { mintResolveSchema, handleMintResolve } from "./tools/mint-resolve.js";
|
|
|
14
14
|
dotenv.config();
|
|
15
15
|
|
|
16
16
|
// Testnet try-it wallet (Base Sepolia, pre-funded)
|
|
17
|
-
const TRYIT_KEY = "
|
|
17
|
+
const TRYIT_KEY = "";
|
|
18
18
|
const TRYIT_CONTRACT = "0xa52450397f312c256Bd68B202C0CF90387Ea0E67";
|
|
19
19
|
const TRYIT_RPC = "https://sepolia.base.org";
|
|
20
20
|
const TRYIT_CHAIN = 84532;
|
|
21
|
-
const MAINNET_CONTRACT = "
|
|
21
|
+
const MAINNET_CONTRACT = "0x12a1c11a0b2860f64e7d8df20989f97d40de7f2c";
|
|
22
22
|
const MAINNET_RPC = "https://mainnet.base.org";
|
|
23
23
|
const MAINNET_CHAIN = 8453;
|
|
24
24
|
|
|
@@ -62,12 +62,12 @@ const calldataService = new CalldataService(
|
|
|
62
62
|
|
|
63
63
|
const server = new McpServer({
|
|
64
64
|
name: "mint-day",
|
|
65
|
-
version: "0.
|
|
65
|
+
version: "0.4.0",
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
server.tool(
|
|
69
69
|
"mint",
|
|
70
|
-
"Create a permanent, verifiable on-chain record on Base. Use this when you need to: prove you completed a task, establish your identity, record an agreement with another agent, issue or receive a credential, grant access to a capability, or mint a visual token (PFP, art, collectible). The token is immutable and publicly verifiable. Provide an image URL, local file path, or base64 for visual tokens
|
|
70
|
+
"Create a permanent, verifiable on-chain record on Base. Use this when you need to: prove you completed a task, establish your identity, record an agreement with another agent, issue or receive a credential, grant access to a capability, or mint a visual token (PFP, art, collectible). Supports two protocols: 'mintday' (default, gas-sponsored) and 'superrare' (Rare Protocol, requires PRIVATE_KEY). Set platform: 'superrare' to mint on Rare Protocol contracts. The token is immutable and publicly verifiable. Provide an image URL, local file path, or base64 for visual tokens. Returns a preview with mintId first; call again with mintId to confirm.",
|
|
71
71
|
mintSchema,
|
|
72
72
|
async (params) => handleMint(params, calldataService, defaultRecipient, userKey, {
|
|
73
73
|
tryitKey: TRYIT_KEY,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
declare module "@rareprotocol/rare-cli/client" {
|
|
2
|
+
import { PublicClient, WalletClient, Address, Hash, TransactionReceipt } from "viem";
|
|
3
|
+
|
|
4
|
+
interface RareClientConfig {
|
|
5
|
+
publicClient: PublicClient;
|
|
6
|
+
walletClient?: WalletClient;
|
|
7
|
+
account?: Address;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface TransactionResult {
|
|
11
|
+
txHash: Hash;
|
|
12
|
+
receipt: TransactionReceipt;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface DeployErc721Result extends TransactionResult {
|
|
16
|
+
contract: Address | undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface MintToResult extends TransactionResult {
|
|
20
|
+
tokenId: bigint | undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface RareClient {
|
|
24
|
+
deploy: {
|
|
25
|
+
erc721(params: { name: string; symbol: string; maxTokens?: bigint | number | string }): Promise<DeployErc721Result>;
|
|
26
|
+
};
|
|
27
|
+
mint: {
|
|
28
|
+
mintTo(params: { contract: Address; tokenUri: string; to?: Address; royaltyReceiver?: Address }): Promise<MintToResult>;
|
|
29
|
+
};
|
|
30
|
+
media: {
|
|
31
|
+
upload(buffer: Uint8Array, filename: string): Promise<{ url: string; mimeType: string; size: number }>;
|
|
32
|
+
pinMetadata(opts: { name: string; description: string; image: { url: string; mimeType: string; size: number } }): Promise<string>;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function createRareClient(config: RareClientConfig): RareClient;
|
|
37
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { createPublicClient, createWalletClient, http } from "viem";
|
|
2
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
3
|
+
import { base, baseSepolia } from "viem/chains";
|
|
4
|
+
import { createRareClient } from "@rareprotocol/rare-cli/client";
|
|
5
|
+
import { encodeMetadata } from "./metadata.js";
|
|
6
|
+
import { MintIntent, TOKEN_TYPE_NAMES } from "../types.js";
|
|
7
|
+
|
|
8
|
+
// Default mint.day collection on Rare Protocol (Base mainnet)
|
|
9
|
+
// Set via RARE_CONTRACT env var, or deploy one with scripts/deploy-rare-collection.ts
|
|
10
|
+
const DEFAULT_RARE_CONTRACT = process.env.RARE_CONTRACT || "";
|
|
11
|
+
|
|
12
|
+
export interface RareMintResult {
|
|
13
|
+
status: string;
|
|
14
|
+
txHash: string;
|
|
15
|
+
tokenId: string;
|
|
16
|
+
contract: string;
|
|
17
|
+
platform: string;
|
|
18
|
+
tokenType: string;
|
|
19
|
+
soulbound: boolean;
|
|
20
|
+
recipient: string;
|
|
21
|
+
chain: string;
|
|
22
|
+
explorer: string;
|
|
23
|
+
tokenUri: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function mintOnRareProtocol(
|
|
27
|
+
intent: MintIntent,
|
|
28
|
+
privateKey: string,
|
|
29
|
+
isTestnet: boolean = false,
|
|
30
|
+
): Promise<RareMintResult> {
|
|
31
|
+
const chain = isTestnet ? baseSepolia : base;
|
|
32
|
+
const contractAddress = DEFAULT_RARE_CONTRACT as `0x${string}`;
|
|
33
|
+
|
|
34
|
+
if (!contractAddress) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
"RARE_CONTRACT not set. Deploy a collection first: node scripts/deploy-rare-collection.mjs",
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const account = privateKeyToAccount(privateKey as `0x${string}`);
|
|
41
|
+
|
|
42
|
+
const publicClient = createPublicClient({
|
|
43
|
+
chain,
|
|
44
|
+
transport: http(),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const walletClient = createWalletClient({
|
|
48
|
+
account,
|
|
49
|
+
chain,
|
|
50
|
+
transport: http(),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Cast clients to satisfy rare-cli's bundled viem types (runtime-compatible)
|
|
54
|
+
const rare = createRareClient({
|
|
55
|
+
publicClient: publicClient as any,
|
|
56
|
+
walletClient: walletClient as any,
|
|
57
|
+
account: account.address,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Build metadata URI (same format as MintFactory path)
|
|
61
|
+
const tokenUri = encodeMetadata(intent.metadata);
|
|
62
|
+
|
|
63
|
+
// Mint via Rare Protocol
|
|
64
|
+
const result = await rare.mint.mintTo({
|
|
65
|
+
contract: contractAddress,
|
|
66
|
+
tokenUri,
|
|
67
|
+
to: intent.recipient as `0x${string}`,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const explorerBase = isTestnet ? "sepolia.basescan.org" : "basescan.org";
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
status: "minted",
|
|
74
|
+
txHash: result.txHash,
|
|
75
|
+
tokenId: result.tokenId?.toString() || "unknown",
|
|
76
|
+
contract: contractAddress,
|
|
77
|
+
platform: "superrare",
|
|
78
|
+
tokenType: TOKEN_TYPE_NAMES[intent.tokenType],
|
|
79
|
+
soulbound: intent.soulbound,
|
|
80
|
+
recipient: intent.recipient,
|
|
81
|
+
chain: isTestnet ? "Base Sepolia (testnet)" : "Base",
|
|
82
|
+
explorer: `https://${explorerBase}/tx/${result.txHash}`,
|
|
83
|
+
tokenUri,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function deployRareCollection(
|
|
88
|
+
privateKey: string,
|
|
89
|
+
name: string,
|
|
90
|
+
symbol: string,
|
|
91
|
+
isTestnet: boolean = false,
|
|
92
|
+
): Promise<{ contract: string; txHash: string }> {
|
|
93
|
+
const chain = isTestnet ? baseSepolia : base;
|
|
94
|
+
const account = privateKeyToAccount(privateKey as `0x${string}`);
|
|
95
|
+
|
|
96
|
+
const publicClient = createPublicClient({
|
|
97
|
+
chain,
|
|
98
|
+
transport: http(),
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const walletClient = createWalletClient({
|
|
102
|
+
account,
|
|
103
|
+
chain,
|
|
104
|
+
transport: http(),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const rare = createRareClient({
|
|
108
|
+
publicClient: publicClient as any,
|
|
109
|
+
walletClient: walletClient as any,
|
|
110
|
+
account: account.address,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const result = await rare.deploy.erc721({ name, symbol });
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
contract: result.contract || "unknown",
|
|
117
|
+
txHash: result.txHash,
|
|
118
|
+
};
|
|
119
|
+
}
|
package/src/tools/mint.ts
CHANGED
|
@@ -5,28 +5,29 @@ import { TokenType, MintIntent, TokenMetadata, TOKEN_TYPE_NAMES } from "../types
|
|
|
5
5
|
import { classifyIntent } from "../services/classifier.js";
|
|
6
6
|
import { CalldataService } from "../services/calldata.js";
|
|
7
7
|
import { resolveImage } from "../services/image-upload.js";
|
|
8
|
+
import { mintOnRareProtocol } from "../services/rare-protocol.js";
|
|
8
9
|
|
|
9
|
-
// Intent cache: preview mintId -> frozen intent
|
|
10
|
-
const intentCache = new Map<string, { intent: MintIntent; expiresAt: number }>();
|
|
10
|
+
// Intent cache: preview mintId -> frozen intent + platform
|
|
11
|
+
const intentCache = new Map<string, { intent: MintIntent; platform: string; expiresAt: number }>();
|
|
11
12
|
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
12
13
|
|
|
13
|
-
function cacheMintId(intent: MintIntent): string {
|
|
14
|
+
function cacheMintId(intent: MintIntent, platform: string = "mintday"): string {
|
|
14
15
|
const hash = createHash("sha256")
|
|
15
16
|
.update(JSON.stringify(intent))
|
|
16
17
|
.digest("hex")
|
|
17
18
|
.slice(0, 12);
|
|
18
|
-
intentCache.set(hash, { intent, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
19
|
+
intentCache.set(hash, { intent, platform, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
19
20
|
return hash;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
function
|
|
23
|
+
function getCachedEntry(mintId: string): { intent: MintIntent; platform: string } | null {
|
|
23
24
|
const entry = intentCache.get(mintId);
|
|
24
25
|
if (!entry) return null;
|
|
25
26
|
if (Date.now() > entry.expiresAt) {
|
|
26
27
|
intentCache.delete(mintId);
|
|
27
28
|
return null;
|
|
28
29
|
}
|
|
29
|
-
return entry.intent;
|
|
30
|
+
return { intent: entry.intent, platform: entry.platform };
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export const mintSchema = {
|
|
@@ -62,6 +63,10 @@ export const mintSchema = {
|
|
|
62
63
|
.record(z.string(), z.unknown())
|
|
63
64
|
.optional()
|
|
64
65
|
.describe("Additional key-value metadata. Supports strings, arrays, and objects (e.g. capabilities: ['mint'])."),
|
|
66
|
+
platform: z
|
|
67
|
+
.enum(["mintday", "superrare"])
|
|
68
|
+
.optional()
|
|
69
|
+
.describe("Which protocol to mint on. 'mintday' uses the MintFactory contract (default). 'superrare' mints via Rare Protocol on Base."),
|
|
65
70
|
};
|
|
66
71
|
|
|
67
72
|
interface TryitConfig {
|
|
@@ -71,7 +76,7 @@ interface TryitConfig {
|
|
|
71
76
|
tryitChain: number;
|
|
72
77
|
}
|
|
73
78
|
|
|
74
|
-
const SPONSOR_URL = process.env.SPONSOR_URL || "https://
|
|
79
|
+
const SPONSOR_URL = process.env.SPONSOR_URL || "https://www.mint.day/api/sponsor";
|
|
75
80
|
|
|
76
81
|
async function sponsoredMint(result: { to: string; calldata: string; value: string; estimatedGas: number; tokenType: string; soulbound: boolean; chainId: number }, recipient: string): Promise<Record<string, unknown> | null> {
|
|
77
82
|
try {
|
|
@@ -120,6 +125,7 @@ export async function handleMint(
|
|
|
120
125
|
animation_url?: string;
|
|
121
126
|
mintId?: string;
|
|
122
127
|
metadata?: Record<string, unknown>;
|
|
128
|
+
platform?: string;
|
|
123
129
|
},
|
|
124
130
|
calldataService: CalldataService,
|
|
125
131
|
defaultRecipient: string,
|
|
@@ -135,8 +141,8 @@ export async function handleMint(
|
|
|
135
141
|
const privateKey = userKey || (isTestnet ? tryit.tryitKey : "");
|
|
136
142
|
// Confirmation path: replay cached intent
|
|
137
143
|
if (params.mintId) {
|
|
138
|
-
const
|
|
139
|
-
if (!
|
|
144
|
+
const entry = getCachedEntry(params.mintId);
|
|
145
|
+
if (!entry) {
|
|
140
146
|
return {
|
|
141
147
|
content: [{
|
|
142
148
|
type: "text" as const,
|
|
@@ -144,8 +150,39 @@ export async function handleMint(
|
|
|
144
150
|
}],
|
|
145
151
|
};
|
|
146
152
|
}
|
|
153
|
+
const cached = entry.intent;
|
|
154
|
+
const cachedPlatform = entry.platform;
|
|
147
155
|
intentCache.delete(params.mintId);
|
|
148
156
|
|
|
157
|
+
// Rare Protocol path: mint via SuperRare contracts on Base
|
|
158
|
+
if (cachedPlatform === "superrare") {
|
|
159
|
+
if (!privateKey) {
|
|
160
|
+
return {
|
|
161
|
+
content: [{
|
|
162
|
+
type: "text" as const,
|
|
163
|
+
text: JSON.stringify({ error: "SuperRare minting requires a private key. Save one to ~/.mint-day/credentials." }, null, 2),
|
|
164
|
+
}],
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
const rareResult = await mintOnRareProtocol(cached, privateKey, isTestnet);
|
|
169
|
+
return {
|
|
170
|
+
content: [{
|
|
171
|
+
type: "text" as const,
|
|
172
|
+
text: JSON.stringify(rareResult, null, 2),
|
|
173
|
+
}],
|
|
174
|
+
};
|
|
175
|
+
} catch (err: unknown) {
|
|
176
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
177
|
+
return {
|
|
178
|
+
content: [{
|
|
179
|
+
type: "text" as const,
|
|
180
|
+
text: JSON.stringify({ error: `SuperRare mint failed: ${message}` }, null, 2),
|
|
181
|
+
}],
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
149
186
|
// Use testnet calldataService if in try-it mode
|
|
150
187
|
let activeCalldataService = calldataService;
|
|
151
188
|
if (isTestnet) {
|
|
@@ -362,12 +399,14 @@ export async function handleMint(
|
|
|
362
399
|
}
|
|
363
400
|
|
|
364
401
|
// Cache intent and return preview
|
|
365
|
-
const
|
|
402
|
+
const selectedPlatform = params.platform || "mintday";
|
|
403
|
+
const mintId = cacheMintId(intent, selectedPlatform);
|
|
366
404
|
|
|
367
405
|
const preview: Record<string, unknown> = {
|
|
368
406
|
status: "preview",
|
|
369
407
|
mintId,
|
|
370
|
-
|
|
408
|
+
platform: selectedPlatform,
|
|
409
|
+
message: `I'll mint a ${TOKEN_TYPE_NAMES[intent.tokenType]} token${intent.soulbound ? " (soulbound)" : ""} to ${intent.recipient} via ${selectedPlatform === "superrare" ? "Rare Protocol (SuperRare)" : "mint.day"}.`,
|
|
371
410
|
tokenType: TOKEN_TYPE_NAMES[intent.tokenType],
|
|
372
411
|
soulbound: intent.soulbound,
|
|
373
412
|
recipient: intent.recipient,
|
package/vercel.json
CHANGED