moltspay 1.6.0 → 2.4.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/.env.example +23 -0
- package/CHANGELOG.md +551 -0
- package/README.md +466 -7
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/index.mjs.map +1 -1
- package/dist/{cdp-DeohBe1o.d.ts → cdp-B5PhDUTC.d.ts} +1 -1
- package/dist/{cdp-p_eHuQpb.d.mts → cdp-D-5Hg3y_.d.mts} +1 -1
- package/dist/chains/index.d.mts +102 -1
- package/dist/chains/index.d.ts +102 -1
- package/dist/chains/index.js +66 -0
- package/dist/chains/index.js.map +1 -1
- package/dist/chains/index.mjs +57 -0
- package/dist/chains/index.mjs.map +1 -1
- package/dist/cli/index.js +6850 -2127
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +6857 -2128
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +348 -1
- package/dist/client/index.d.ts +348 -1
- package/dist/client/index.js +1462 -43
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +1469 -51
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/web/index.d.mts +17 -1
- package/dist/client/web/index.mjs +11 -0
- package/dist/client/web/index.mjs.map +1 -1
- package/dist/facilitators/index.d.mts +663 -4
- package/dist/facilitators/index.d.ts +663 -4
- package/dist/facilitators/index.js +1292 -10
- package/dist/facilitators/index.js.map +1 -1
- package/dist/facilitators/index.mjs +1268 -9
- package/dist/facilitators/index.mjs.map +1 -1
- package/dist/index.d.mts +78 -3
- package/dist/index.d.ts +78 -3
- package/dist/index.js +4229 -556
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4214 -548
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/index.js +1462 -45
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/index.mjs +1473 -56
- package/dist/mcp/index.mjs.map +1 -1
- package/dist/{registry-OsEO2dOu.d.mts → registry-DIo0WNoO.d.mts} +8 -1
- package/dist/{registry-OsEO2dOu.d.ts → registry-DIo0WNoO.d.ts} +8 -1
- package/dist/server/index.d.mts +336 -2
- package/dist/server/index.d.ts +336 -2
- package/dist/server/index.js +2516 -188
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +2516 -188
- package/dist/server/index.mjs.map +1 -1
- package/dist/verify/index.js.map +1 -1
- package/dist/verify/index.mjs.map +1 -1
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +20 -2
- package/schemas/moltspay.services.schema.json +211 -6
- package/scripts/postinstall.js +91 -0
|
@@ -32,21 +32,162 @@
|
|
|
32
32
|
},
|
|
33
33
|
"chain": {
|
|
34
34
|
"type": "string",
|
|
35
|
-
"enum": ["base", "polygon", "base_sepolia", "tempo_moderato", "bnb", "bnb_testnet", "solana", "solana_devnet"],
|
|
35
|
+
"enum": ["base", "polygon", "base_sepolia", "tempo_moderato", "bnb", "bnb_testnet", "solana", "solana_devnet", "alipay", "wechat", "balance"],
|
|
36
36
|
"default": "base",
|
|
37
|
-
"description": "Single chain mode (use 'chains' for multi-chain)"
|
|
37
|
+
"description": "Single chain mode (use 'chains' for multi-chain). 'alipay'/'wechat' are fiat rails (2.0+/2.1+), 'balance' is the custodial rail (2.2+), none are blockchains."
|
|
38
38
|
},
|
|
39
39
|
"chains": {
|
|
40
40
|
"type": "array",
|
|
41
|
-
"description": "Supported chains. EVM chains use 'wallet', Solana chains use 'solana_wallet'.",
|
|
41
|
+
"description": "Supported chains/rails. EVM chains use 'wallet', Solana chains use 'solana_wallet', 'alipay' (2.0+) uses 'provider.alipay', 'wechat' (2.1+) uses 'provider.wechat'.",
|
|
42
42
|
"items": {
|
|
43
43
|
"type": "string",
|
|
44
|
-
"enum": ["base", "polygon", "base_sepolia", "tempo_moderato", "bnb", "bnb_testnet", "solana", "solana_devnet"]
|
|
44
|
+
"enum": ["base", "polygon", "base_sepolia", "tempo_moderato", "bnb", "bnb_testnet", "solana", "solana_devnet", "alipay", "wechat", "balance"]
|
|
45
45
|
},
|
|
46
46
|
"examples": [
|
|
47
47
|
["base", "polygon", "solana_devnet"],
|
|
48
|
-
["base", "base_sepolia", "solana", "solana_devnet"]
|
|
48
|
+
["base", "base_sepolia", "solana", "solana_devnet"],
|
|
49
|
+
["base", "polygon", "alipay"]
|
|
49
50
|
]
|
|
51
|
+
},
|
|
52
|
+
"alipay": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"description": "Alipay AI 收 provider config (2.0+). Required when 'chains' contains 'alipay'.",
|
|
55
|
+
"required": ["seller_id", "app_id", "seller_name", "service_id_default", "private_key_path", "alipay_public_key_path"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"seller_id": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"pattern": "^[0-9]{16}$",
|
|
60
|
+
"description": "Merchant Alipay ID (16 digits)"
|
|
61
|
+
},
|
|
62
|
+
"app_id": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"pattern": "^[0-9]{16}$",
|
|
65
|
+
"description": "Application ID from Alipay Open Platform"
|
|
66
|
+
},
|
|
67
|
+
"seller_name": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"description": "Merchant legal name (shown in 'method.seller_name' of the 402 challenge)"
|
|
70
|
+
},
|
|
71
|
+
"service_id_default": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"description": "Default service_id when a service entry doesn't override it (e.g. 'API_XXXXXXXXXXXXXXXX')"
|
|
74
|
+
},
|
|
75
|
+
"private_key_path": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "Path to the RSA2 merchant private key PEM file (relative to moltspay.services.json)"
|
|
78
|
+
},
|
|
79
|
+
"alipay_public_key_path": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"description": "Path to the Alipay platform public key PEM file (relative to moltspay.services.json)"
|
|
82
|
+
},
|
|
83
|
+
"gateway_url": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"format": "uri",
|
|
86
|
+
"default": "https://openapi.alipay.com/gateway.do",
|
|
87
|
+
"description": "Open API gateway URL (use 'https://openapi.alipaydev.com/gateway.do' for sandbox)"
|
|
88
|
+
},
|
|
89
|
+
"sign_type": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"enum": ["RSA2"],
|
|
92
|
+
"default": "RSA2",
|
|
93
|
+
"description": "Signature algorithm. Only RSA2 is supported in 2.0."
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"wechat": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"description": "WeChat Pay v3 Native provider config (2.1+). Required when 'chains' contains 'wechat'.",
|
|
100
|
+
"required": ["mchid", "appid", "serial_no", "private_key_path", "notify_url"],
|
|
101
|
+
"properties": {
|
|
102
|
+
"mchid": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"description": "Merchant id (商户号)"
|
|
105
|
+
},
|
|
106
|
+
"appid": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"description": "App id (official account / mini-program / app)"
|
|
109
|
+
},
|
|
110
|
+
"serial_no": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"description": "Merchant API certificate serial number"
|
|
113
|
+
},
|
|
114
|
+
"private_key_path": {
|
|
115
|
+
"type": "string",
|
|
116
|
+
"description": "Path to the merchant RSA private key PEM file (relative to moltspay.services.json)"
|
|
117
|
+
},
|
|
118
|
+
"platform_public_key_path": {
|
|
119
|
+
"type": "string",
|
|
120
|
+
"description": "Path to the WeChat platform certificate public key PEM (enables response verification)"
|
|
121
|
+
},
|
|
122
|
+
"apiv3_key": {
|
|
123
|
+
"type": "string",
|
|
124
|
+
"minLength": 32,
|
|
125
|
+
"maxLength": 32,
|
|
126
|
+
"description": "APIv3 key (32 bytes). Only needed for callback decryption (Phase 2)"
|
|
127
|
+
},
|
|
128
|
+
"notify_url": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"format": "uri",
|
|
131
|
+
"description": "Async result notify URL. Required by Native order create even when polling."
|
|
132
|
+
},
|
|
133
|
+
"api_base": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"format": "uri",
|
|
136
|
+
"default": "https://api.mch.weixin.qq.com",
|
|
137
|
+
"description": "Open API base URL"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"balance": {
|
|
142
|
+
"type": "object",
|
|
143
|
+
"description": "Custodial balance rail config (2.2+). Required when 'chains' contains 'balance'. Enabling requires Node.js >= 22.5.",
|
|
144
|
+
"required": ["db_path"],
|
|
145
|
+
"properties": {
|
|
146
|
+
"db_path": {
|
|
147
|
+
"type": "string",
|
|
148
|
+
"description": "SQLite ledger file path (relative to moltspay.services.json); created on first start"
|
|
149
|
+
},
|
|
150
|
+
"currency": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"enum": ["USD", "CNY"],
|
|
153
|
+
"default": "USD",
|
|
154
|
+
"description": "Ledger quote currency. Recorded once and enforced on reopen (a mismatch refuses to start). CNY funds 1:1 from WeChat (payer_total is fen)."
|
|
155
|
+
},
|
|
156
|
+
"single_limit": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"pattern": "^\\d+(\\.\\d{1,2})?$",
|
|
159
|
+
"default": "5.00",
|
|
160
|
+
"description": "Default per-transaction limit for new buyers (decimal string, ledger currency)"
|
|
161
|
+
},
|
|
162
|
+
"daily_limit": {
|
|
163
|
+
"type": "string",
|
|
164
|
+
"pattern": "^\\d+(\\.\\d{1,2})?$",
|
|
165
|
+
"default": "10.00",
|
|
166
|
+
"description": "Default daily limit for new buyers (decimal string, ledger currency)"
|
|
167
|
+
},
|
|
168
|
+
"topup_packs": {
|
|
169
|
+
"type": "array",
|
|
170
|
+
"minItems": 1,
|
|
171
|
+
"items": { "type": "string", "pattern": "^\\d+(\\.\\d{1,2})?$" },
|
|
172
|
+
"description": "Offered recharge amounts in ledger currency (2.3+), e.g. [\"20.00\", \"50.00\"]"
|
|
173
|
+
},
|
|
174
|
+
"default_pack": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"pattern": "^\\d+(\\.\\d{1,2})?$",
|
|
177
|
+
"description": "Pack the client auto-selects when a 402 finds an insufficient balance (2.3+). Must be one of topup_packs."
|
|
178
|
+
},
|
|
179
|
+
"auto_topup_max": {
|
|
180
|
+
"type": "string",
|
|
181
|
+
"pattern": "^\\d+(\\.\\d{1,2})?$",
|
|
182
|
+
"description": "Ceiling on client auto-topup without explicit pack selection (2.3+). Must be >= the largest topup_pack."
|
|
183
|
+
},
|
|
184
|
+
"auth_mode": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"enum": ["off", "shadow", "enforce"],
|
|
187
|
+
"default": "off",
|
|
188
|
+
"description": "Balance spend authentication (2.4+). 'off': signature not checked (default, backward-compatible; buyer_id keeps bearer semantics). 'shadow': verify per-request signatures and log what would be denied, without blocking (use to confirm every client signs before tightening). 'enforce': reject unsigned/invalid/wrong-signer deductions with 401. The account's signer address is TOFU-bound on first signed use and anchored to the WeChat payer openid at top-up."
|
|
189
|
+
}
|
|
190
|
+
}
|
|
50
191
|
}
|
|
51
192
|
}
|
|
52
193
|
},
|
|
@@ -74,7 +215,43 @@
|
|
|
74
215
|
"price": { "type": "number", "minimum": 0, "description": "Price in currency units" },
|
|
75
216
|
"currency": { "type": "string", "enum": ["USDC", "USDT"], "default": "USDC" },
|
|
76
217
|
"input": { "type": "object", "description": "Input parameters schema" },
|
|
77
|
-
"output": { "type": "object", "description": "Output schema" }
|
|
218
|
+
"output": { "type": "object", "description": "Output schema" },
|
|
219
|
+
"alipay": {
|
|
220
|
+
"type": "object",
|
|
221
|
+
"description": "Alipay AI 收 per-service config (2.0+). Set when this service accepts CNY payments.",
|
|
222
|
+
"required": ["price_cny", "goods_name"],
|
|
223
|
+
"properties": {
|
|
224
|
+
"service_id": {
|
|
225
|
+
"type": "string",
|
|
226
|
+
"description": "Per-service service_id (defaults to provider.alipay.service_id_default)"
|
|
227
|
+
},
|
|
228
|
+
"price_cny": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"pattern": "^\\d+(\\.\\d{1,2})?$",
|
|
231
|
+
"description": "CNY price as decimal string in 元 (e.g. '7.00' = 7 CNY, NOT cents)"
|
|
232
|
+
},
|
|
233
|
+
"goods_name": {
|
|
234
|
+
"type": "string",
|
|
235
|
+
"description": "Goods name shown to the user in the Alipay app"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
"wechat": {
|
|
240
|
+
"type": "object",
|
|
241
|
+
"description": "WeChat Pay Native per-service config (2.1+). Set when this service accepts CNY payments.",
|
|
242
|
+
"required": ["price_cny", "description"],
|
|
243
|
+
"properties": {
|
|
244
|
+
"price_cny": {
|
|
245
|
+
"type": "string",
|
|
246
|
+
"pattern": "^\\d+(\\.\\d{1,2})?$",
|
|
247
|
+
"description": "CNY price as decimal string in yuan (e.g. '10.00' = 10 CNY, NOT fen)"
|
|
248
|
+
},
|
|
249
|
+
"description": {
|
|
250
|
+
"type": "string",
|
|
251
|
+
"description": "Order description shown to the payer in the WeChat app"
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
78
255
|
}
|
|
79
256
|
}
|
|
80
257
|
}
|
|
@@ -90,6 +267,34 @@
|
|
|
90
267
|
"services": [
|
|
91
268
|
{ "id": "text-to-video", "function": "textToVideo", "price": 0.99, "currency": "USDC" }
|
|
92
269
|
]
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"provider": {
|
|
273
|
+
"name": "My Shop",
|
|
274
|
+
"wallet": "0x0000000000000000000000000000000000000000",
|
|
275
|
+
"chains": ["base", "polygon", "alipay"],
|
|
276
|
+
"alipay": {
|
|
277
|
+
"seller_id": "2088000000000000",
|
|
278
|
+
"app_id": "2021000000000000",
|
|
279
|
+
"seller_name": "Example Merchant Co., Ltd.",
|
|
280
|
+
"service_id_default": "API_XXXXXXXXXXXXXXXX",
|
|
281
|
+
"private_key_path": "./cert/ALIPAY_PRIVATE_KEY.txt",
|
|
282
|
+
"alipay_public_key_path": "./cert/ALIPAY_PUBLIC_KEY.txt"
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
"services": [
|
|
286
|
+
{
|
|
287
|
+
"id": "text-to-video",
|
|
288
|
+
"function": "textToVideo",
|
|
289
|
+
"price": 0.99,
|
|
290
|
+
"currency": "USDC",
|
|
291
|
+
"alipay": {
|
|
292
|
+
"service_id": "API_XXXXXXXXXXXXXXXX",
|
|
293
|
+
"price_cny": "7.00",
|
|
294
|
+
"goods_name": "Demo Video"
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
]
|
|
93
298
|
}
|
|
94
299
|
]
|
|
95
300
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* postinstall — greet, then provision the alipay-bot CLI.
|
|
5
|
+
*
|
|
6
|
+
* alipay-bot is a runtime dependency of the Alipay payment rail. It is NOT on
|
|
7
|
+
* npm (Alipay distributes it from their own CDN) and is licensed UNLICENSED, so
|
|
8
|
+
* it can neither be a package.json dependency nor be bundled into this package.
|
|
9
|
+
* Instead, installing moltspay provisions it automatically by invoking the
|
|
10
|
+
* @alipay/agent-payment helper's `install-cli`, which downloads the CLI directly
|
|
11
|
+
* from Alipay's CDN onto THIS machine — we never redistribute it ourselves.
|
|
12
|
+
*
|
|
13
|
+
* The user opted into this by installing moltspay (alipay-bot is a declared
|
|
14
|
+
* dependency of the Alipay rail), so provisioning it is part of that install.
|
|
15
|
+
*
|
|
16
|
+
* Best-effort by design: provisioning failure (offline / CDN unreachable) prints
|
|
17
|
+
* an actionable notice but NEVER fails `npm install`. The runtime `ensureCli`
|
|
18
|
+
* gate is the real enforcement point and re-states the one command to run.
|
|
19
|
+
*
|
|
20
|
+
* Opt out with MOLTSPAY_SKIP_CLI_INSTALL=1 (e.g. CI / sandboxes).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const { spawnSync } = require('child_process');
|
|
24
|
+
const path = require('path');
|
|
25
|
+
const fs = require('fs');
|
|
26
|
+
|
|
27
|
+
const banner = `
|
|
28
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
29
|
+
║ ║
|
|
30
|
+
║ 🎉 Thanks for installing MoltsPay! ║
|
|
31
|
+
║ ║
|
|
32
|
+
║ Quick Start: ║
|
|
33
|
+
║ npx moltspay init # Setup wallet ║
|
|
34
|
+
║ npx moltspay status # Check balance ║
|
|
35
|
+
║ npx moltspay validate . # Validate service config ║
|
|
36
|
+
║ ║
|
|
37
|
+
║ 📖 Docs: https://moltspay.com/docs ║
|
|
38
|
+
║ 💬 Support: https://discord.gg/QwCJgVBxVK ║
|
|
39
|
+
║ ║
|
|
40
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
41
|
+
`;
|
|
42
|
+
console.log(banner);
|
|
43
|
+
|
|
44
|
+
const PROVISION_HINT = 'npx -y @alipay/agent-payment install-cli';
|
|
45
|
+
|
|
46
|
+
function warnManual(reason) {
|
|
47
|
+
console.warn(
|
|
48
|
+
`\n[moltspay] alipay-bot CLI 未能自动安装(${reason})。\n` +
|
|
49
|
+
` Alipay 支付轨在使用前需手动安装:\n` +
|
|
50
|
+
` ${PROVISION_HINT}\n`,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (process.env.MOLTSPAY_SKIP_CLI_INSTALL === '1') {
|
|
55
|
+
console.log('[moltspay] MOLTSPAY_SKIP_CLI_INSTALL=1 — 跳过 alipay-bot 自动安装。');
|
|
56
|
+
console.log(`[moltspay] 需要时手动安装:${PROVISION_HINT}`);
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
console.log('[moltspay] 正在从支付宝官方 CDN 安装 alipay-bot CLI(Alipay 支付轨所需)…');
|
|
61
|
+
|
|
62
|
+
// Prefer the helper we already pulled in as a declared dependency (no extra
|
|
63
|
+
// network for the helper itself). Fall back to `npx` if it isn't resolvable
|
|
64
|
+
// (odd layout / installed with --ignore-scripts on the dep).
|
|
65
|
+
let result;
|
|
66
|
+
let helperCli = null;
|
|
67
|
+
try {
|
|
68
|
+
const helperPkgJson = require.resolve('@alipay/agent-payment/package.json');
|
|
69
|
+
const helperDir = path.dirname(helperPkgJson);
|
|
70
|
+
const bin = JSON.parse(fs.readFileSync(helperPkgJson, 'utf8')).bin;
|
|
71
|
+
const rel = typeof bin === 'string' ? bin : bin && bin['agent-payment'];
|
|
72
|
+
if (rel) helperCli = path.join(helperDir, rel);
|
|
73
|
+
} catch {
|
|
74
|
+
helperCli = null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (helperCli && fs.existsSync(helperCli)) {
|
|
78
|
+
result = spawnSync(process.execPath, [helperCli, 'install-cli'], { stdio: 'inherit' });
|
|
79
|
+
} else {
|
|
80
|
+
const npx = process.platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
81
|
+
result = spawnSync(npx, ['-y', '@alipay/agent-payment', 'install-cli'], { stdio: 'inherit' });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!result || result.error || result.status !== 0) {
|
|
85
|
+
warnManual(result && result.error ? result.error.message : '离线或无法访问 *.alipay.com');
|
|
86
|
+
} else {
|
|
87
|
+
console.log('[moltspay] alipay-bot CLI 安装完成。');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Never block the install over an optional rail's provisioning.
|
|
91
|
+
process.exit(0);
|