moltspay 1.2.0 → 1.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 +161 -17
- package/dist/cdp/index.d.mts +1 -1
- package/dist/cdp/index.d.ts +1 -1
- package/dist/cdp/index.js +60 -30408
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/index.mjs +44 -30400
- package/dist/cdp/index.mjs.map +1 -1
- package/dist/cdp-DeohBe1o.d.ts +66 -0
- package/dist/cdp-p_eHuQpb.d.mts +66 -0
- package/dist/chains/index.d.mts +1 -1
- package/dist/chains/index.d.ts +1 -1
- package/dist/chains/index.js +36 -40
- package/dist/chains/index.js.map +1 -1
- package/dist/chains/index.mjs +36 -40
- package/dist/chains/index.mjs.map +1 -1
- package/dist/cli/index.js +997 -174
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1001 -174
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +27 -4
- package/dist/client/index.d.ts +27 -4
- package/dist/client/index.js +217 -60
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +207 -60
- package/dist/client/index.mjs.map +1 -1
- package/dist/facilitators/index.d.mts +15 -47
- package/dist/facilitators/index.d.ts +15 -47
- package/dist/facilitators/index.js +273 -34
- package/dist/facilitators/index.js.map +1 -1
- package/dist/facilitators/index.mjs +272 -34
- package/dist/facilitators/index.mjs.map +1 -1
- package/dist/{index-B3v8IWjM.d.mts → index-On9ZaGDW.d.mts} +2 -1
- package/dist/{index-B3v8IWjM.d.ts → index-On9ZaGDW.d.ts} +2 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +792 -30657
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +782 -30657
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +17 -0
- package/dist/server/index.d.ts +17 -0
- package/dist/server/index.js +513 -48
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +513 -48
- package/dist/server/index.mjs.map +1 -1
- package/dist/verify/index.d.mts +1 -1
- package/dist/verify/index.d.ts +1 -1
- package/dist/verify/index.js +36 -40
- package/dist/verify/index.js.map +1 -1
- package/dist/verify/index.mjs +36 -40
- package/dist/verify/index.mjs.map +1 -1
- package/dist/wallet/index.d.mts +1 -1
- package/dist/wallet/index.d.ts +1 -1
- package/dist/wallet/index.js +36 -40
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +36 -40
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +5 -2
package/dist/client/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as TokenSymbol } from '../index-
|
|
1
|
+
import { T as TokenSymbol } from '../index-On9ZaGDW.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* MoltsPay Client Types
|
|
@@ -78,8 +78,8 @@ interface PayOptions {
|
|
|
78
78
|
token?: TokenSymbol;
|
|
79
79
|
/** Auto-select token based on balance (default: false) */
|
|
80
80
|
autoSelect?: boolean;
|
|
81
|
-
/** Chain to pay on (base or
|
|
82
|
-
chain?: 'base' | 'polygon';
|
|
81
|
+
/** Chain to pay on (base, polygon, or base_sepolia, default: base) */
|
|
82
|
+
chain?: 'base' | 'polygon' | 'base_sepolia';
|
|
83
83
|
}
|
|
84
84
|
declare class MoltsPayClient {
|
|
85
85
|
private configDir;
|
|
@@ -166,13 +166,36 @@ declare class MoltsPayClient {
|
|
|
166
166
|
native: number;
|
|
167
167
|
}>;
|
|
168
168
|
/**
|
|
169
|
-
* Get wallet balances on all supported chains (Base + Polygon)
|
|
169
|
+
* Get wallet balances on all supported chains (Base + Polygon + Tempo)
|
|
170
170
|
*/
|
|
171
171
|
getAllBalances(): Promise<Record<string, {
|
|
172
172
|
usdc: number;
|
|
173
173
|
usdt: number;
|
|
174
174
|
native: number;
|
|
175
|
+
tempo?: {
|
|
176
|
+
pathUSD: number;
|
|
177
|
+
alphaUSD: number;
|
|
178
|
+
betaUSD: number;
|
|
179
|
+
thetaUSD: number;
|
|
180
|
+
};
|
|
175
181
|
}>>;
|
|
182
|
+
/**
|
|
183
|
+
* Pay for a service using MPP (Machine Payments Protocol)
|
|
184
|
+
*
|
|
185
|
+
* This implements the MPP flow manually for EOA wallets:
|
|
186
|
+
* 1. Request service → get 402 with WWW-Authenticate
|
|
187
|
+
* 2. Parse payment requirements
|
|
188
|
+
* 3. Execute transfer on Tempo chain
|
|
189
|
+
* 4. Retry with transaction hash as credential
|
|
190
|
+
*
|
|
191
|
+
* @param url - Full URL of the MPP-enabled endpoint
|
|
192
|
+
* @param options - Request options (body, headers)
|
|
193
|
+
* @returns Response from the service
|
|
194
|
+
*/
|
|
195
|
+
payWithMPP(url: string, options?: {
|
|
196
|
+
body?: any;
|
|
197
|
+
headers?: Record<string, string>;
|
|
198
|
+
}): Promise<any>;
|
|
176
199
|
}
|
|
177
200
|
|
|
178
201
|
export { type ClientConfig, MoltsPayClient, type MoltsPayClientOptions, type PayOptions, type PaymentRequired, type ProviderInfo, type ServiceInfo, type ServicesResponse, type VerifyResponse, type WalletData };
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as TokenSymbol } from '../index-
|
|
1
|
+
import { T as TokenSymbol } from '../index-On9ZaGDW.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* MoltsPay Client Types
|
|
@@ -78,8 +78,8 @@ interface PayOptions {
|
|
|
78
78
|
token?: TokenSymbol;
|
|
79
79
|
/** Auto-select token based on balance (default: false) */
|
|
80
80
|
autoSelect?: boolean;
|
|
81
|
-
/** Chain to pay on (base or
|
|
82
|
-
chain?: 'base' | 'polygon';
|
|
81
|
+
/** Chain to pay on (base, polygon, or base_sepolia, default: base) */
|
|
82
|
+
chain?: 'base' | 'polygon' | 'base_sepolia';
|
|
83
83
|
}
|
|
84
84
|
declare class MoltsPayClient {
|
|
85
85
|
private configDir;
|
|
@@ -166,13 +166,36 @@ declare class MoltsPayClient {
|
|
|
166
166
|
native: number;
|
|
167
167
|
}>;
|
|
168
168
|
/**
|
|
169
|
-
* Get wallet balances on all supported chains (Base + Polygon)
|
|
169
|
+
* Get wallet balances on all supported chains (Base + Polygon + Tempo)
|
|
170
170
|
*/
|
|
171
171
|
getAllBalances(): Promise<Record<string, {
|
|
172
172
|
usdc: number;
|
|
173
173
|
usdt: number;
|
|
174
174
|
native: number;
|
|
175
|
+
tempo?: {
|
|
176
|
+
pathUSD: number;
|
|
177
|
+
alphaUSD: number;
|
|
178
|
+
betaUSD: number;
|
|
179
|
+
thetaUSD: number;
|
|
180
|
+
};
|
|
175
181
|
}>>;
|
|
182
|
+
/**
|
|
183
|
+
* Pay for a service using MPP (Machine Payments Protocol)
|
|
184
|
+
*
|
|
185
|
+
* This implements the MPP flow manually for EOA wallets:
|
|
186
|
+
* 1. Request service → get 402 with WWW-Authenticate
|
|
187
|
+
* 2. Parse payment requirements
|
|
188
|
+
* 3. Execute transfer on Tempo chain
|
|
189
|
+
* 4. Retry with transaction hash as credential
|
|
190
|
+
*
|
|
191
|
+
* @param url - Full URL of the MPP-enabled endpoint
|
|
192
|
+
* @param options - Request options (body, headers)
|
|
193
|
+
* @returns Response from the service
|
|
194
|
+
*/
|
|
195
|
+
payWithMPP(url: string, options?: {
|
|
196
|
+
body?: any;
|
|
197
|
+
headers?: Record<string, string>;
|
|
198
|
+
}): Promise<any>;
|
|
176
199
|
}
|
|
177
200
|
|
|
178
201
|
export { type ClientConfig, MoltsPayClient, type MoltsPayClientOptions, type PayOptions, type PaymentRequired, type ProviderInfo, type ServiceInfo, type ServicesResponse, type VerifyResponse, type WalletData };
|
package/dist/client/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/client/index.ts
|
|
@@ -39,12 +49,15 @@ var CHAINS = {
|
|
|
39
49
|
USDC: {
|
|
40
50
|
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
41
51
|
decimals: 6,
|
|
42
|
-
symbol: "USDC"
|
|
52
|
+
symbol: "USDC",
|
|
53
|
+
eip712Name: "USD Coin"
|
|
54
|
+
// EIP-712 domain name
|
|
43
55
|
},
|
|
44
56
|
USDT: {
|
|
45
57
|
address: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2",
|
|
46
58
|
decimals: 6,
|
|
47
|
-
symbol: "USDT"
|
|
59
|
+
symbol: "USDT",
|
|
60
|
+
eip712Name: "Tether USD"
|
|
48
61
|
}
|
|
49
62
|
},
|
|
50
63
|
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
@@ -61,12 +74,15 @@ var CHAINS = {
|
|
|
61
74
|
USDC: {
|
|
62
75
|
address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
63
76
|
decimals: 6,
|
|
64
|
-
symbol: "USDC"
|
|
77
|
+
symbol: "USDC",
|
|
78
|
+
eip712Name: "USD Coin"
|
|
65
79
|
},
|
|
66
80
|
USDT: {
|
|
67
81
|
address: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
68
82
|
decimals: 6,
|
|
69
|
-
symbol: "USDT"
|
|
83
|
+
symbol: "USDT",
|
|
84
|
+
eip712Name: "(PoS) Tether USD"
|
|
85
|
+
// Polygon uses this name
|
|
70
86
|
}
|
|
71
87
|
},
|
|
72
88
|
usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
@@ -74,27 +90,6 @@ var CHAINS = {
|
|
|
74
90
|
explorerTx: "https://polygonscan.com/tx/",
|
|
75
91
|
avgBlockTime: 2
|
|
76
92
|
},
|
|
77
|
-
ethereum: {
|
|
78
|
-
name: "Ethereum",
|
|
79
|
-
chainId: 1,
|
|
80
|
-
rpc: "https://eth.llamarpc.com",
|
|
81
|
-
tokens: {
|
|
82
|
-
USDC: {
|
|
83
|
-
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
84
|
-
decimals: 6,
|
|
85
|
-
symbol: "USDC"
|
|
86
|
-
},
|
|
87
|
-
USDT: {
|
|
88
|
-
address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
89
|
-
decimals: 6,
|
|
90
|
-
symbol: "USDT"
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
94
|
-
explorer: "https://etherscan.io/address/",
|
|
95
|
-
explorerTx: "https://etherscan.io/tx/",
|
|
96
|
-
avgBlockTime: 12
|
|
97
|
-
},
|
|
98
93
|
// ============ Testnet ============
|
|
99
94
|
base_sepolia: {
|
|
100
95
|
name: "Base Sepolia",
|
|
@@ -104,13 +99,17 @@ var CHAINS = {
|
|
|
104
99
|
USDC: {
|
|
105
100
|
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
106
101
|
decimals: 6,
|
|
107
|
-
symbol: "USDC"
|
|
102
|
+
symbol: "USDC",
|
|
103
|
+
eip712Name: "USDC"
|
|
104
|
+
// Testnet USDC uses 'USDC' not 'USD Coin'
|
|
108
105
|
},
|
|
109
106
|
USDT: {
|
|
110
107
|
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
111
108
|
// Same as USDC on testnet (no official USDT)
|
|
112
109
|
decimals: 6,
|
|
113
|
-
symbol: "USDT"
|
|
110
|
+
symbol: "USDT",
|
|
111
|
+
eip712Name: "USDC"
|
|
112
|
+
// Uses same contract as USDC
|
|
114
113
|
}
|
|
115
114
|
},
|
|
116
115
|
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
@@ -118,27 +117,34 @@ var CHAINS = {
|
|
|
118
117
|
explorerTx: "https://sepolia.basescan.org/tx/",
|
|
119
118
|
avgBlockTime: 2
|
|
120
119
|
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
// ============ Tempo Testnet (Moderato) ============
|
|
121
|
+
tempo_moderato: {
|
|
122
|
+
name: "Tempo Moderato",
|
|
123
|
+
chainId: 42431,
|
|
124
|
+
rpc: "https://rpc.moderato.tempo.xyz",
|
|
125
125
|
tokens: {
|
|
126
|
+
// TIP-20 stablecoins on Tempo testnet (from mppx SDK)
|
|
127
|
+
// Note: Tempo uses USD as native gas token, not ETH
|
|
126
128
|
USDC: {
|
|
127
|
-
address: "
|
|
129
|
+
address: "0x20c0000000000000000000000000000000000000",
|
|
130
|
+
// pathUSD - primary testnet stablecoin
|
|
128
131
|
decimals: 6,
|
|
129
|
-
symbol: "USDC"
|
|
132
|
+
symbol: "USDC",
|
|
133
|
+
eip712Name: "pathUSD"
|
|
130
134
|
},
|
|
131
135
|
USDT: {
|
|
132
|
-
address: "
|
|
133
|
-
//
|
|
136
|
+
address: "0x20c0000000000000000000000000000000000001",
|
|
137
|
+
// alphaUSD
|
|
134
138
|
decimals: 6,
|
|
135
|
-
symbol: "USDT"
|
|
139
|
+
symbol: "USDT",
|
|
140
|
+
eip712Name: "alphaUSD"
|
|
136
141
|
}
|
|
137
142
|
},
|
|
138
|
-
usdc: "
|
|
139
|
-
explorer: "https://
|
|
140
|
-
explorerTx: "https://
|
|
141
|
-
avgBlockTime:
|
|
143
|
+
usdc: "0x20c0000000000000000000000000000000000000",
|
|
144
|
+
explorer: "https://explore.testnet.tempo.xyz/address/",
|
|
145
|
+
explorerTx: "https://explore.testnet.tempo.xyz/tx/",
|
|
146
|
+
avgBlockTime: 0.5
|
|
147
|
+
// ~500ms finality
|
|
142
148
|
}
|
|
143
149
|
};
|
|
144
150
|
function getChain(name) {
|
|
@@ -301,7 +307,7 @@ Server accepts: ${serverChains.join(", ")}`
|
|
|
301
307
|
} else {
|
|
302
308
|
throw new Error(
|
|
303
309
|
`Server accepts: ${serverChains.join(", ")}
|
|
304
|
-
Please specify: --chain base
|
|
310
|
+
Please specify: --chain base, --chain polygon, or --chain base_sepolia`
|
|
305
311
|
);
|
|
306
312
|
}
|
|
307
313
|
}
|
|
@@ -343,13 +349,19 @@ Please specify: --chain base or --chain polygon`
|
|
|
343
349
|
if (!payTo) {
|
|
344
350
|
throw new Error("Missing payTo address in payment requirements");
|
|
345
351
|
}
|
|
346
|
-
const
|
|
352
|
+
const domainOverride = req.extra && typeof req.extra === "object" && req.extra.name ? { name: req.extra.name, version: req.extra.version || "2" } : void 0;
|
|
353
|
+
const authorization = await this.signEIP3009(payTo, amount, chain, token, domainOverride);
|
|
347
354
|
const tokenConfig = chain.tokens[token];
|
|
348
|
-
const
|
|
355
|
+
const extra = req.extra && typeof req.extra === "object" ? req.extra : {
|
|
356
|
+
name: tokenConfig.eip712Name || "USD Coin",
|
|
357
|
+
version: "2"
|
|
358
|
+
};
|
|
349
359
|
const payload = {
|
|
350
360
|
x402Version: X402_VERSION,
|
|
361
|
+
scheme: "exact",
|
|
362
|
+
network,
|
|
351
363
|
payload: authorization,
|
|
352
|
-
//
|
|
364
|
+
// { authorization: {...}, signature: "0x..." }
|
|
353
365
|
accepted: {
|
|
354
366
|
scheme: "exact",
|
|
355
367
|
network,
|
|
@@ -357,7 +369,7 @@ Please specify: --chain base or --chain polygon`
|
|
|
357
369
|
amount: amountRaw,
|
|
358
370
|
payTo,
|
|
359
371
|
maxTimeoutSeconds: req.maxTimeoutSeconds || 300,
|
|
360
|
-
extra
|
|
372
|
+
extra
|
|
361
373
|
}
|
|
362
374
|
};
|
|
363
375
|
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
@@ -387,7 +399,7 @@ Please specify: --chain base or --chain polygon`
|
|
|
387
399
|
* This only signs - no on-chain transaction, no gas needed.
|
|
388
400
|
* Supports both USDC and USDT.
|
|
389
401
|
*/
|
|
390
|
-
async signEIP3009(to, amount, chain, token = "USDC") {
|
|
402
|
+
async signEIP3009(to, amount, chain, token = "USDC", domainOverride) {
|
|
391
403
|
const validAfter = 0;
|
|
392
404
|
const validBefore = Math.floor(Date.now() / 1e3) + 3600;
|
|
393
405
|
const nonce = import_ethers.ethers.hexlify(import_ethers.ethers.randomBytes(32));
|
|
@@ -401,10 +413,11 @@ Please specify: --chain base or --chain polygon`
|
|
|
401
413
|
validBefore: validBefore.toString(),
|
|
402
414
|
nonce
|
|
403
415
|
};
|
|
404
|
-
const tokenName = token === "USDC" ? "USD Coin" : "Tether USD";
|
|
416
|
+
const tokenName = domainOverride?.name || tokenConfig.eip712Name || (token === "USDC" ? "USD Coin" : "Tether USD");
|
|
417
|
+
const tokenVersion = domainOverride?.version || "2";
|
|
405
418
|
const domain = {
|
|
406
419
|
name: tokenName,
|
|
407
|
-
version:
|
|
420
|
+
version: tokenVersion,
|
|
408
421
|
chainId: chain.chainId,
|
|
409
422
|
verifyingContract: tokenConfig.address
|
|
410
423
|
};
|
|
@@ -567,30 +580,59 @@ Please specify: --chain base or --chain polygon`
|
|
|
567
580
|
};
|
|
568
581
|
}
|
|
569
582
|
/**
|
|
570
|
-
* Get wallet balances on all supported chains (Base + Polygon)
|
|
583
|
+
* Get wallet balances on all supported chains (Base + Polygon + Tempo)
|
|
571
584
|
*/
|
|
572
585
|
async getAllBalances() {
|
|
573
586
|
if (!this.wallet) {
|
|
574
587
|
throw new Error("Client not initialized");
|
|
575
588
|
}
|
|
576
|
-
const supportedChains = ["base", "polygon"];
|
|
589
|
+
const supportedChains = ["base", "polygon", "base_sepolia", "tempo_moderato"];
|
|
577
590
|
const tokenAbi = ["function balanceOf(address) view returns (uint256)"];
|
|
578
591
|
const results = {};
|
|
592
|
+
const tempoTokens = {
|
|
593
|
+
pathUSD: "0x20c0000000000000000000000000000000000000",
|
|
594
|
+
alphaUSD: "0x20c0000000000000000000000000000000000001",
|
|
595
|
+
betaUSD: "0x20c0000000000000000000000000000000000002",
|
|
596
|
+
thetaUSD: "0x20c0000000000000000000000000000000000003"
|
|
597
|
+
};
|
|
579
598
|
await Promise.all(
|
|
580
599
|
supportedChains.map(async (chainName) => {
|
|
581
600
|
try {
|
|
582
601
|
const chain = getChain(chainName);
|
|
583
602
|
const provider = new import_ethers.ethers.JsonRpcProvider(chain.rpc);
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
603
|
+
if (chainName === "tempo_moderato") {
|
|
604
|
+
const [nativeBalance, pathUSD, alphaUSD, betaUSD, thetaUSD] = await Promise.all([
|
|
605
|
+
provider.getBalance(this.wallet.address),
|
|
606
|
+
new import_ethers.ethers.Contract(tempoTokens.pathUSD, tokenAbi, provider).balanceOf(this.wallet.address),
|
|
607
|
+
new import_ethers.ethers.Contract(tempoTokens.alphaUSD, tokenAbi, provider).balanceOf(this.wallet.address),
|
|
608
|
+
new import_ethers.ethers.Contract(tempoTokens.betaUSD, tokenAbi, provider).balanceOf(this.wallet.address),
|
|
609
|
+
new import_ethers.ethers.Contract(tempoTokens.thetaUSD, tokenAbi, provider).balanceOf(this.wallet.address)
|
|
610
|
+
]);
|
|
611
|
+
results[chainName] = {
|
|
612
|
+
usdc: parseFloat(import_ethers.ethers.formatUnits(pathUSD, 6)),
|
|
613
|
+
// pathUSD as default USDC
|
|
614
|
+
usdt: parseFloat(import_ethers.ethers.formatUnits(alphaUSD, 6)),
|
|
615
|
+
// alphaUSD as default USDT
|
|
616
|
+
native: parseFloat(import_ethers.ethers.formatEther(nativeBalance)),
|
|
617
|
+
tempo: {
|
|
618
|
+
pathUSD: parseFloat(import_ethers.ethers.formatUnits(pathUSD, 6)),
|
|
619
|
+
alphaUSD: parseFloat(import_ethers.ethers.formatUnits(alphaUSD, 6)),
|
|
620
|
+
betaUSD: parseFloat(import_ethers.ethers.formatUnits(betaUSD, 6)),
|
|
621
|
+
thetaUSD: parseFloat(import_ethers.ethers.formatUnits(thetaUSD, 6))
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
} else {
|
|
625
|
+
const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([
|
|
626
|
+
provider.getBalance(this.wallet.address),
|
|
627
|
+
new import_ethers.ethers.Contract(chain.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet.address),
|
|
628
|
+
new import_ethers.ethers.Contract(chain.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet.address)
|
|
629
|
+
]);
|
|
630
|
+
results[chainName] = {
|
|
631
|
+
usdc: parseFloat(import_ethers.ethers.formatUnits(usdcBalance, chain.tokens.USDC.decimals)),
|
|
632
|
+
usdt: parseFloat(import_ethers.ethers.formatUnits(usdtBalance, chain.tokens.USDT.decimals)),
|
|
633
|
+
native: parseFloat(import_ethers.ethers.formatEther(nativeBalance))
|
|
634
|
+
};
|
|
635
|
+
}
|
|
594
636
|
} catch (err) {
|
|
595
637
|
results[chainName] = { usdc: 0, usdt: 0, native: 0 };
|
|
596
638
|
}
|
|
@@ -598,6 +640,121 @@ Please specify: --chain base or --chain polygon`
|
|
|
598
640
|
);
|
|
599
641
|
return results;
|
|
600
642
|
}
|
|
643
|
+
/**
|
|
644
|
+
* Pay for a service using MPP (Machine Payments Protocol)
|
|
645
|
+
*
|
|
646
|
+
* This implements the MPP flow manually for EOA wallets:
|
|
647
|
+
* 1. Request service → get 402 with WWW-Authenticate
|
|
648
|
+
* 2. Parse payment requirements
|
|
649
|
+
* 3. Execute transfer on Tempo chain
|
|
650
|
+
* 4. Retry with transaction hash as credential
|
|
651
|
+
*
|
|
652
|
+
* @param url - Full URL of the MPP-enabled endpoint
|
|
653
|
+
* @param options - Request options (body, headers)
|
|
654
|
+
* @returns Response from the service
|
|
655
|
+
*/
|
|
656
|
+
async payWithMPP(url, options = {}) {
|
|
657
|
+
if (!this.wallet || !this.walletData) {
|
|
658
|
+
throw new Error("Client not initialized. Run: npx moltspay init");
|
|
659
|
+
}
|
|
660
|
+
const { privateKeyToAccount } = await import("viem/accounts");
|
|
661
|
+
const { createWalletClient, createPublicClient, http } = await import("viem");
|
|
662
|
+
const { tempoModerato } = await import("viem/chains");
|
|
663
|
+
const { Actions } = await import("viem/tempo");
|
|
664
|
+
const privateKey = this.walletData.privateKey;
|
|
665
|
+
const account = privateKeyToAccount(privateKey);
|
|
666
|
+
console.log(`[MoltsPay] Making MPP request to: ${url}`);
|
|
667
|
+
console.log(`[MoltsPay] Using account: ${account.address}`);
|
|
668
|
+
const initResponse = await fetch(url, {
|
|
669
|
+
method: "POST",
|
|
670
|
+
headers: {
|
|
671
|
+
"Content-Type": "application/json",
|
|
672
|
+
...options.headers
|
|
673
|
+
},
|
|
674
|
+
body: options.body ? JSON.stringify(options.body) : void 0
|
|
675
|
+
});
|
|
676
|
+
if (initResponse.status !== 402) {
|
|
677
|
+
if (initResponse.ok) {
|
|
678
|
+
return initResponse.json();
|
|
679
|
+
}
|
|
680
|
+
const errorText = await initResponse.text();
|
|
681
|
+
throw new Error(`Request failed (${initResponse.status}): ${errorText}`);
|
|
682
|
+
}
|
|
683
|
+
const wwwAuth = initResponse.headers.get("www-authenticate");
|
|
684
|
+
if (!wwwAuth || !wwwAuth.toLowerCase().includes("payment")) {
|
|
685
|
+
throw new Error("No WWW-Authenticate Payment challenge in 402 response");
|
|
686
|
+
}
|
|
687
|
+
console.log(`[MoltsPay] Got 402, parsing payment challenge...`);
|
|
688
|
+
const parseAuthParam = (header, key) => {
|
|
689
|
+
const match = header.match(new RegExp(`${key}="([^"]+)"`, "i"));
|
|
690
|
+
return match ? match[1] : null;
|
|
691
|
+
};
|
|
692
|
+
const challengeId = parseAuthParam(wwwAuth, "id");
|
|
693
|
+
const method = parseAuthParam(wwwAuth, "method");
|
|
694
|
+
const realm = parseAuthParam(wwwAuth, "realm");
|
|
695
|
+
const requestB64 = parseAuthParam(wwwAuth, "request");
|
|
696
|
+
if (method !== "tempo") {
|
|
697
|
+
throw new Error(`Unsupported payment method: ${method}`);
|
|
698
|
+
}
|
|
699
|
+
if (!requestB64) {
|
|
700
|
+
throw new Error("Missing request in WWW-Authenticate");
|
|
701
|
+
}
|
|
702
|
+
const requestJson = Buffer.from(requestB64, "base64").toString("utf-8");
|
|
703
|
+
const paymentRequest = JSON.parse(requestJson);
|
|
704
|
+
console.log(`[MoltsPay] Payment request:`, paymentRequest);
|
|
705
|
+
const { amount, currency, recipient, methodDetails } = paymentRequest;
|
|
706
|
+
const chainId = methodDetails?.chainId || 42431;
|
|
707
|
+
console.log(`[MoltsPay] Executing transfer on Tempo (chainId: ${chainId})...`);
|
|
708
|
+
console.log(`[MoltsPay] Amount: ${amount}, To: ${recipient}`);
|
|
709
|
+
const tempoChain = { ...tempoModerato, feeToken: currency };
|
|
710
|
+
const publicClient = createPublicClient({
|
|
711
|
+
chain: tempoChain,
|
|
712
|
+
transport: http("https://rpc.moderato.tempo.xyz")
|
|
713
|
+
});
|
|
714
|
+
const walletClient = createWalletClient({
|
|
715
|
+
account,
|
|
716
|
+
chain: tempoChain,
|
|
717
|
+
transport: http("https://rpc.moderato.tempo.xyz")
|
|
718
|
+
});
|
|
719
|
+
const txHash = await Actions.token.transfer(walletClient, {
|
|
720
|
+
to: recipient,
|
|
721
|
+
amount: BigInt(amount),
|
|
722
|
+
token: currency
|
|
723
|
+
});
|
|
724
|
+
console.log(`[MoltsPay] Transaction sent: ${txHash}`);
|
|
725
|
+
console.log(`[MoltsPay] Waiting for confirmation...`);
|
|
726
|
+
await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
727
|
+
console.log(`[MoltsPay] Transaction confirmed!`);
|
|
728
|
+
const challenge = {
|
|
729
|
+
id: challengeId,
|
|
730
|
+
realm,
|
|
731
|
+
method: "tempo",
|
|
732
|
+
intent: "charge",
|
|
733
|
+
request: paymentRequest
|
|
734
|
+
};
|
|
735
|
+
const credential = {
|
|
736
|
+
challenge,
|
|
737
|
+
payload: { hash: txHash, type: "hash" },
|
|
738
|
+
source: `did:pkh:eip155:${chainId}:${account.address}`
|
|
739
|
+
};
|
|
740
|
+
const credentialB64 = Buffer.from(JSON.stringify(credential)).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
741
|
+
console.log(`[MoltsPay] Retrying with payment credential...`);
|
|
742
|
+
const paidResponse = await fetch(url, {
|
|
743
|
+
method: "POST",
|
|
744
|
+
headers: {
|
|
745
|
+
"Content-Type": "application/json",
|
|
746
|
+
"Authorization": `Payment ${credentialB64}`,
|
|
747
|
+
...options.headers
|
|
748
|
+
},
|
|
749
|
+
body: options.body ? JSON.stringify(options.body) : void 0
|
|
750
|
+
});
|
|
751
|
+
if (!paidResponse.ok) {
|
|
752
|
+
const errorText = await paidResponse.text();
|
|
753
|
+
throw new Error(`Payment verification failed (${paidResponse.status}): ${errorText}`);
|
|
754
|
+
}
|
|
755
|
+
console.log(`[MoltsPay] Payment verified! Service completed.`);
|
|
756
|
+
return paidResponse.json();
|
|
757
|
+
}
|
|
601
758
|
};
|
|
602
759
|
// Annotate the CommonJS export names for ESM import in node:
|
|
603
760
|
0 && (module.exports = {
|