@heraldprotocol/mpp 0.0.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.
@@ -0,0 +1,397 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
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
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/server/index.ts
31
+ var server_exports = {};
32
+ __export(server_exports, {
33
+ charge: () => charge2,
34
+ zerog: () => zerog
35
+ });
36
+ module.exports = __toCommonJS(server_exports);
37
+
38
+ // src/server/Charge.ts
39
+ var import_mppx2 = require("mppx");
40
+ var import_viem2 = require("viem");
41
+ var import_accounts = require("viem/accounts");
42
+ var import_actions = require("viem/actions");
43
+
44
+ // src/defaults.ts
45
+ var chainId = {
46
+ mainnet: 16661,
47
+ testnet: 16602
48
+ };
49
+ var USDC_E = "0x1f3aa82227281ca364bfb3d253b0f1af1da6473e";
50
+ var currency = {
51
+ [chainId.mainnet]: USDC_E
52
+ };
53
+ var decimals = 6;
54
+ var rpcUrl = {
55
+ [chainId.mainnet]: "https://evmrpc.0g.ai",
56
+ [chainId.testnet]: "https://evmrpc-testnet.0g.ai"
57
+ };
58
+ var erc3009Abi = [
59
+ {
60
+ type: "function",
61
+ name: "transferWithAuthorization",
62
+ inputs: [
63
+ { name: "from", type: "address" },
64
+ { name: "to", type: "address" },
65
+ { name: "value", type: "uint256" },
66
+ { name: "validAfter", type: "uint256" },
67
+ { name: "validBefore", type: "uint256" },
68
+ { name: "nonce", type: "bytes32" },
69
+ { name: "v", type: "uint8" },
70
+ { name: "r", type: "bytes32" },
71
+ { name: "s", type: "bytes32" }
72
+ ],
73
+ outputs: [],
74
+ stateMutability: "nonpayable"
75
+ },
76
+ {
77
+ type: "function",
78
+ name: "receiveWithAuthorization",
79
+ inputs: [
80
+ { name: "from", type: "address" },
81
+ { name: "to", type: "address" },
82
+ { name: "value", type: "uint256" },
83
+ { name: "validAfter", type: "uint256" },
84
+ { name: "validBefore", type: "uint256" },
85
+ { name: "nonce", type: "bytes32" },
86
+ { name: "v", type: "uint8" },
87
+ { name: "r", type: "bytes32" },
88
+ { name: "s", type: "bytes32" }
89
+ ],
90
+ outputs: [],
91
+ stateMutability: "nonpayable"
92
+ },
93
+ {
94
+ type: "function",
95
+ name: "name",
96
+ inputs: [],
97
+ outputs: [{ name: "", type: "string" }],
98
+ stateMutability: "view"
99
+ },
100
+ {
101
+ type: "function",
102
+ name: "version",
103
+ inputs: [],
104
+ outputs: [{ name: "", type: "string" }],
105
+ stateMutability: "view"
106
+ }
107
+ ];
108
+ var erc3009Tokens = {
109
+ [USDC_E.toLowerCase()]: {
110
+ name: "Bridged USDC",
111
+ version: "2"
112
+ }
113
+ };
114
+ function resolveCurrency(parameters) {
115
+ const id = parameters.chainId ?? (parameters.testnet ? chainId.testnet : chainId.mainnet);
116
+ const resolved = currency[id];
117
+ if (!resolved)
118
+ throw new Error(`No default currency configured for chainId ${id}.`);
119
+ return resolved;
120
+ }
121
+
122
+ // src/Methods.ts
123
+ var import_mppx = require("mppx");
124
+ var import_viem = require("viem");
125
+ var charge = import_mppx.Method.from({
126
+ name: "zerog",
127
+ intent: "charge",
128
+ schema: {
129
+ credential: {
130
+ payload: import_mppx.z.discriminatedUnion("type", [
131
+ import_mppx.z.object({ hash: import_mppx.z.hash(), type: import_mppx.z.literal("hash") }),
132
+ import_mppx.z.object({
133
+ type: import_mppx.z.literal("authorization"),
134
+ from: import_mppx.z.string(),
135
+ to: import_mppx.z.string(),
136
+ value: import_mppx.z.string(),
137
+ validAfter: import_mppx.z.string(),
138
+ validBefore: import_mppx.z.string(),
139
+ nonce: import_mppx.z.string(),
140
+ signature: import_mppx.z.string()
141
+ })
142
+ ])
143
+ },
144
+ request: import_mppx.z.pipe(
145
+ import_mppx.z.object({
146
+ amount: import_mppx.z.amount(),
147
+ chainId: import_mppx.z.optional(import_mppx.z.number()),
148
+ currency: import_mppx.z.string(),
149
+ decimals: import_mppx.z.number(),
150
+ description: import_mppx.z.optional(import_mppx.z.string()),
151
+ externalId: import_mppx.z.optional(import_mppx.z.string()),
152
+ recipient: import_mppx.z.optional(import_mppx.z.string())
153
+ }),
154
+ import_mppx.z.transform(({ amount, chainId: chainId2, decimals: decimals2, ...rest }) => ({
155
+ ...rest,
156
+ amount: (0, import_viem.parseUnits)(amount, decimals2).toString(),
157
+ ...chainId2 !== void 0 ? { methodDetails: { chainId: chainId2 } } : {}
158
+ }))
159
+ )
160
+ }
161
+ });
162
+
163
+ // src/server/Charge.ts
164
+ function charge2(parameters = {}) {
165
+ const {
166
+ amount,
167
+ currency: currency2 = resolveCurrency(parameters),
168
+ decimals: decimals2 = decimals,
169
+ description,
170
+ externalId,
171
+ recipient,
172
+ waitForConfirmation = true
173
+ } = parameters;
174
+ const store = parameters.store ?? import_mppx2.Store.memory();
175
+ if (currency2.toLowerCase() in erc3009Tokens && !parameters.account) {
176
+ throw new Error(
177
+ "ERC-3009 requires an `account` parameter so the server can sign and broadcast the transferWithAuthorization transaction."
178
+ );
179
+ }
180
+ const serverAccount = parameters.account ? typeof parameters.account === "string" ? (0, import_accounts.parseAccount)(parameters.account) : parameters.account : void 0;
181
+ const resolveClient = async (chainId2) => {
182
+ if (parameters.getClient) return parameters.getClient({ chainId: chainId2 });
183
+ const id = chainId2 ?? chainId.mainnet;
184
+ const url = rpcUrl[id];
185
+ if (!url) throw new Error(`No RPC URL configured for chainId ${id}.`);
186
+ const { createClient, http } = await import("viem");
187
+ return createClient({ chain: { id }, transport: http(url) });
188
+ };
189
+ return import_mppx2.Method.toServer(charge, {
190
+ defaults: {
191
+ amount,
192
+ currency: currency2,
193
+ decimals: decimals2,
194
+ description,
195
+ externalId,
196
+ recipient
197
+ },
198
+ async request({ request }) {
199
+ const chainId2 = await (async () => {
200
+ if (request.chainId) return request.chainId;
201
+ if (parameters.testnet) return chainId.testnet;
202
+ return (await resolveClient(void 0)).chain?.id;
203
+ })();
204
+ const client = await (async () => {
205
+ try {
206
+ return await resolveClient(chainId2);
207
+ } catch {
208
+ throw new Error(`No client configured with chainId ${chainId2}.`);
209
+ }
210
+ })();
211
+ if (client.chain?.id !== chainId2)
212
+ throw new Error(`Client not configured with chainId ${chainId2}.`);
213
+ return { ...request, chainId: chainId2 };
214
+ },
215
+ async verify({ credential, request }) {
216
+ const { challenge } = credential;
217
+ const { chainId: chainId2 } = request;
218
+ const client = await resolveClient(chainId2);
219
+ const { request: challengeRequest } = challenge;
220
+ const challengeAmount = challengeRequest.amount;
221
+ const challengeCurrency = challengeRequest.currency;
222
+ const challengeRecipient = challengeRequest.recipient;
223
+ const expires = challenge.expires;
224
+ if (expires && new Date(expires) < /* @__PURE__ */ new Date()) {
225
+ throw new Error(`Payment expired at ${expires}.`);
226
+ }
227
+ const payload = credential.payload;
228
+ switch (payload.type) {
229
+ case "hash": {
230
+ const hash = payload.hash;
231
+ await assertHashUnused(store, hash);
232
+ const sender = extractDidAddress(credential.source);
233
+ if (!sender)
234
+ throw new Error(
235
+ "Hash credential is missing a valid `source` DID \u2014 cannot verify sender."
236
+ );
237
+ const receipt = await (0, import_actions.getTransactionReceipt)(client, { hash });
238
+ const transferLogs = (0, import_viem2.parseEventLogs)({
239
+ abi: import_viem2.erc20Abi,
240
+ eventName: "Transfer",
241
+ logs: receipt.logs
242
+ });
243
+ const match = transferLogs.find(
244
+ (log) => (0, import_viem2.isAddressEqual)(log.address, challengeCurrency) && (0, import_viem2.isAddressEqual)(log.args.from, sender) && (0, import_viem2.isAddressEqual)(log.args.to, challengeRecipient) && log.args.value.toString() === challengeAmount
245
+ );
246
+ if (!match)
247
+ throw new MismatchError(
248
+ "Payment verification failed: no matching ERC-20 transfer found.",
249
+ {
250
+ sender,
251
+ amount: challengeAmount,
252
+ currency: challengeCurrency,
253
+ recipient: challengeRecipient
254
+ }
255
+ );
256
+ await markHashUsed(store, hash);
257
+ return toReceipt(receipt);
258
+ }
259
+ case "authorization": {
260
+ if (!serverAccount) {
261
+ throw new Error(
262
+ "Received ERC-3009 authorization credential but no server `account` is configured. Set `account` in charge parameters to broadcast transferWithAuthorization."
263
+ );
264
+ }
265
+ const { from, to, value, validAfter, validBefore, nonce, signature } = payload;
266
+ const r = `0x${signature.slice(2, 66)}`;
267
+ const s = `0x${signature.slice(66, 130)}`;
268
+ const v = parseInt(signature.slice(130, 132), 16);
269
+ if (!(0, import_viem2.isAddressEqual)(to, challengeRecipient))
270
+ throw new MismatchError(
271
+ "Authorization recipient does not match challenge.",
272
+ { expected: challengeRecipient, actual: to }
273
+ );
274
+ if (value !== challengeAmount)
275
+ throw new MismatchError(
276
+ "Authorization amount does not match challenge.",
277
+ { expected: challengeAmount, actual: value }
278
+ );
279
+ const validBeforeTs = Number(validBefore);
280
+ if (validBeforeTs > 0 && validBeforeTs < Math.floor(Date.now() / 1e3)) {
281
+ throw new Error(
282
+ `ERC-3009 authorization expired (validBefore: ${validBefore}).`
283
+ );
284
+ }
285
+ const hash = (0, import_viem2.keccak256)(signature);
286
+ await assertHashUnused(store, hash);
287
+ await markHashUsed(store, hash);
288
+ if (waitForConfirmation) {
289
+ const receipt = await (0, import_actions.sendTransactionSync)(client, {
290
+ account: serverAccount,
291
+ chain: client.chain,
292
+ to: challengeCurrency,
293
+ data: (0, import_viem2.encodeFunctionData)({
294
+ abi: erc3009Abi,
295
+ functionName: "transferWithAuthorization",
296
+ args: [
297
+ from,
298
+ to,
299
+ BigInt(value),
300
+ BigInt(validAfter),
301
+ BigInt(validBefore),
302
+ nonce,
303
+ v,
304
+ r,
305
+ s
306
+ ]
307
+ })
308
+ });
309
+ return toReceipt(receipt);
310
+ }
311
+ const txHash = await (0, import_actions.sendTransaction)(client, {
312
+ account: serverAccount,
313
+ chain: client.chain,
314
+ to: challengeCurrency,
315
+ data: (0, import_viem2.encodeFunctionData)({
316
+ abi: erc3009Abi,
317
+ functionName: "transferWithAuthorization",
318
+ args: [
319
+ from,
320
+ to,
321
+ BigInt(value),
322
+ BigInt(validAfter),
323
+ BigInt(validBefore),
324
+ nonce,
325
+ v,
326
+ r,
327
+ s
328
+ ]
329
+ })
330
+ });
331
+ return {
332
+ method: "zerog",
333
+ status: "success",
334
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
335
+ reference: txHash
336
+ };
337
+ }
338
+ default:
339
+ throw new Error(
340
+ `Unsupported credential type "${payload.type}".`
341
+ );
342
+ }
343
+ }
344
+ });
345
+ }
346
+ function getHashStoreKey(hash) {
347
+ return `mppx:charge:${hash.toLowerCase()}`;
348
+ }
349
+ async function assertHashUnused(store, hash) {
350
+ const seen = await store.get(getHashStoreKey(hash));
351
+ if (seen !== null) throw new Error("Transaction hash has already been used.");
352
+ }
353
+ async function markHashUsed(store, hash) {
354
+ await store.put(getHashStoreKey(hash), Date.now());
355
+ }
356
+ function toReceipt(receipt) {
357
+ const { status, transactionHash } = receipt;
358
+ if (status !== "success") {
359
+ throw new Error(`Transaction reverted: ${transactionHash}`);
360
+ }
361
+ return {
362
+ method: "zerog",
363
+ status: "success",
364
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
365
+ reference: transactionHash
366
+ };
367
+ }
368
+ function extractDidAddress(source) {
369
+ if (!source) return void 0;
370
+ const match = /^did:pkh:eip155:\d+:(0x[0-9a-fA-F]{40})$/.exec(source);
371
+ return match ? match[1] : void 0;
372
+ }
373
+ var MismatchError = class extends Error {
374
+ constructor(reason, details) {
375
+ super(
376
+ [
377
+ reason,
378
+ ...Object.entries(details).map(([k, v]) => ` - ${k}: ${v}`)
379
+ ].join("\n")
380
+ );
381
+ this.name = "MismatchError";
382
+ }
383
+ };
384
+
385
+ // src/server/Methods.ts
386
+ function zerog(parameters) {
387
+ return [zerog.charge(parameters)];
388
+ }
389
+ ((zerog2) => {
390
+ zerog2.charge = charge2;
391
+ })(zerog || (zerog = {}));
392
+ // Annotate the CommonJS export names for ESM import in node:
393
+ 0 && (module.exports = {
394
+ charge,
395
+ zerog
396
+ });
397
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/index.ts","../../src/server/Charge.ts","../../src/defaults.ts","../../src/Methods.ts","../../src/server/Methods.ts"],"sourcesContent":["export { charge } from \"./Charge.js\";\nexport { zerog } from \"./Methods.js\";\n","import type { Account, Address, Chain, Client, TransactionReceipt } from \"viem\";\nimport { Method, Store } from \"mppx\";\nimport {\n encodeFunctionData,\n erc20Abi,\n isAddressEqual,\n keccak256,\n parseEventLogs,\n} from \"viem\";\nimport { parseAccount } from \"viem/accounts\";\nimport {\n getTransactionReceipt,\n sendTransaction,\n sendTransactionSync,\n} from \"viem/actions\";\n\nimport type { MaybePromise } from \"../types.js\";\nimport * as defaults from \"../defaults.js\";\nimport * as Methods from \"../Methods.js\";\n\n/**\n * Creates a 0G charge method intent for usage on the server.\n *\n * @example\n * ```ts\n * import { zerog } from \"@heraldprotocol/mpp/server\";\n *\n * const charge = zerog.charge({\n * recipient: \"0x...\",\n * currency: \"0x...\",\n * account: privateKeyToAccount(\"0x...\"),\n * });\n * ```\n */\nexport function charge(parameters: charge.Parameters = {}): Method.AnyServer {\n const {\n amount,\n currency = defaults.resolveCurrency(parameters),\n decimals = defaults.decimals,\n description,\n externalId,\n recipient,\n waitForConfirmation = true,\n } = parameters;\n const store = (parameters.store ??\n Store.memory()) as Store.Store<charge.StoreItemMap>;\n\n if (currency.toLowerCase() in defaults.erc3009Tokens && !parameters.account) {\n throw new Error(\n \"ERC-3009 requires an `account` parameter so the server can sign and broadcast \" +\n \"the transferWithAuthorization transaction.\"\n );\n }\n\n const serverAccount = parameters.account\n ? typeof parameters.account === \"string\"\n ? parseAccount(parameters.account)\n : parameters.account\n : undefined;\n\n const resolveClient = async (\n chainId?: number | undefined\n ): Promise<Client> => {\n if (parameters.getClient) return parameters.getClient({ chainId });\n const id = chainId ?? defaults.chainId.mainnet;\n const url = defaults.rpcUrl[id];\n if (!url) throw new Error(`No RPC URL configured for chainId ${id}.`);\n const { createClient, http } = await import(\"viem\");\n return createClient({ chain: { id } as Chain, transport: http(url) });\n };\n\n return Method.toServer(Methods.charge, {\n defaults: {\n amount,\n currency,\n decimals,\n description,\n externalId,\n recipient,\n } as never,\n\n async request({ request }) {\n const chainId = await (async () => {\n if (request.chainId) return request.chainId;\n if (parameters.testnet) return defaults.chainId.testnet;\n return (await resolveClient(undefined)).chain?.id;\n })();\n\n const client = await (async () => {\n try {\n return await resolveClient(chainId);\n } catch {\n throw new Error(`No client configured with chainId ${chainId}.`);\n }\n })();\n if (client.chain?.id !== chainId)\n throw new Error(`Client not configured with chainId ${chainId}.`);\n\n return { ...request, chainId };\n },\n\n async verify({ credential, request }) {\n const { challenge } = credential;\n const { chainId } = request;\n\n const client = await resolveClient(chainId);\n\n const { request: challengeRequest } = challenge;\n const challengeAmount = challengeRequest.amount as string;\n const challengeCurrency = challengeRequest.currency as Address;\n const challengeRecipient = challengeRequest.recipient as Address;\n const expires = challenge.expires;\n\n if (expires && new Date(expires) < new Date()) {\n throw new Error(`Payment expired at ${expires}.`);\n }\n\n const payload = credential.payload;\n\n switch (payload.type) {\n case \"hash\": {\n const hash = payload.hash as `0x${string}`;\n await assertHashUnused(store, hash);\n\n const sender = extractDidAddress(credential.source);\n if (!sender)\n throw new Error(\n \"Hash credential is missing a valid `source` DID — cannot verify sender.\"\n );\n\n const receipt = await getTransactionReceipt(client, { hash });\n\n const transferLogs = parseEventLogs({\n abi: erc20Abi,\n eventName: \"Transfer\",\n logs: receipt.logs,\n });\n\n const match = transferLogs.find(\n (log) =>\n isAddressEqual(log.address, challengeCurrency) &&\n isAddressEqual(log.args.from, sender) &&\n isAddressEqual(log.args.to, challengeRecipient) &&\n log.args.value.toString() === challengeAmount\n );\n\n if (!match)\n throw new MismatchError(\n \"Payment verification failed: no matching ERC-20 transfer found.\",\n {\n sender,\n amount: challengeAmount,\n currency: challengeCurrency,\n recipient: challengeRecipient,\n }\n );\n\n await markHashUsed(store, hash);\n\n return toReceipt(receipt);\n }\n\n case \"authorization\": {\n if (!serverAccount) {\n throw new Error(\n \"Received ERC-3009 authorization credential but no server `account` is configured. \" +\n \"Set `account` in charge parameters to broadcast transferWithAuthorization.\"\n );\n }\n\n const { from, to, value, validAfter, validBefore, nonce, signature } =\n payload as {\n from: string;\n to: string;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: string;\n signature: string;\n };\n\n // Split signature into v, r, s for the contract call\n const r = `0x${signature.slice(2, 66)}` as `0x${string}`;\n const s = `0x${signature.slice(66, 130)}` as `0x${string}`;\n const v = parseInt(signature.slice(130, 132), 16);\n\n // Validate authorization parameters match the challenge\n if (!isAddressEqual(to as Address, challengeRecipient))\n throw new MismatchError(\n \"Authorization recipient does not match challenge.\",\n { expected: challengeRecipient, actual: to }\n );\n\n if (value !== challengeAmount)\n throw new MismatchError(\n \"Authorization amount does not match challenge.\",\n { expected: challengeAmount, actual: value }\n );\n\n // Check expiry from the authorization itself\n const validBeforeTs = Number(validBefore);\n if (\n validBeforeTs > 0 &&\n validBeforeTs < Math.floor(Date.now() / 1000)\n ) {\n throw new Error(\n `ERC-3009 authorization expired (validBefore: ${validBefore}).`\n );\n }\n\n const hash = keccak256(signature as `0x${string}`);\n await assertHashUnused(store, hash);\n await markHashUsed(store, hash);\n\n if (waitForConfirmation) {\n const receipt = await sendTransactionSync(client, {\n account: serverAccount,\n chain: client.chain,\n to: challengeCurrency,\n data: encodeFunctionData({\n abi: defaults.erc3009Abi,\n functionName: \"transferWithAuthorization\",\n args: [\n from as Address,\n to as Address,\n BigInt(value),\n BigInt(validAfter),\n BigInt(validBefore),\n nonce as `0x${string}`,\n v,\n r as `0x${string}`,\n s as `0x${string}`,\n ],\n }),\n } as never);\n\n return toReceipt(receipt);\n }\n\n const txHash = await sendTransaction(client, {\n account: serverAccount,\n chain: client.chain,\n to: challengeCurrency,\n data: encodeFunctionData({\n abi: defaults.erc3009Abi,\n functionName: \"transferWithAuthorization\",\n args: [\n from as Address,\n to as Address,\n BigInt(value),\n BigInt(validAfter),\n BigInt(validBefore),\n nonce as `0x${string}`,\n v,\n r as `0x${string}`,\n s as `0x${string}`,\n ],\n }),\n } as never);\n\n return {\n method: \"zerog\" as const,\n status: \"success\" as const,\n timestamp: new Date().toISOString(),\n reference: txHash,\n };\n }\n\n default:\n throw new Error(\n `Unsupported credential type \"${(payload as { type: string }).type}\".`\n );\n }\n },\n });\n}\n\nexport declare namespace charge {\n type StoreItemMap = {\n [key: `mppx:charge:${string}`]: number;\n };\n\n type Parameters = {\n /** Default payment amount (human-readable, e.g. \"1.50\"). */\n amount?: string | undefined;\n /** ERC-20 token contract address. */\n currency?: string | undefined;\n /** Token decimals. @default 6 */\n decimals?: number | undefined;\n /** Human-readable description. */\n description?: string | undefined;\n /** External identifier to echo back in receipt. */\n externalId?: string | undefined;\n /** Recipient address for payments. */\n recipient?: string | undefined;\n /** Testnet mode. */\n testnet?: boolean | undefined;\n /**\n * Whether to wait for the charge transaction to confirm on-chain.\n * @default true\n */\n waitForConfirmation?: boolean | undefined;\n /** Function that returns a viem Client for the given chain ID. */\n getClient?:\n | ((parameters: { chainId?: number | undefined }) => MaybePromise<Client>)\n | undefined;\n /**\n * Server account used to broadcast `transferWithAuthorization` transactions.\n * Required when accepting `authorization` payloads. The server pays gas\n * from this account.\n */\n account?: Account | Address | undefined;\n /**\n * Store for transaction hash replay protection.\n *\n * Use a shared store in multi-instance deployments so consumed hashes are\n * visible across all server instances.\n */\n store?: Store.Store | undefined;\n };\n}\n\n/** @internal */\nfunction getHashStoreKey(hash: `0x${string}`): `mppx:charge:${string}` {\n return `mppx:charge:${hash.toLowerCase()}`;\n}\n\n/** @internal */\nasync function assertHashUnused(\n store: Store.Store<charge.StoreItemMap>,\n hash: `0x${string}`\n): Promise<void> {\n const seen = await store.get(getHashStoreKey(hash));\n if (seen !== null) throw new Error(\"Transaction hash has already been used.\");\n}\n\n/** @internal */\nasync function markHashUsed(\n store: Store.Store<charge.StoreItemMap>,\n hash: `0x${string}`\n): Promise<void> {\n await store.put(getHashStoreKey(hash), Date.now());\n}\n\n/** @internal */\nfunction toReceipt(receipt: TransactionReceipt) {\n const { status, transactionHash } = receipt;\n if (status !== \"success\") {\n throw new Error(`Transaction reverted: ${transactionHash}`);\n }\n return {\n method: \"zerog\" as const,\n status: \"success\" as const,\n timestamp: new Date().toISOString(),\n reference: transactionHash,\n };\n}\n\n/**\n * Extracts an Ethereum address from a `did:pkh:eip155:<chainId>:<address>` DID.\n * Returns `undefined` if the source is missing or malformed.\n * @internal\n */\nfunction extractDidAddress(source: string | undefined): Address | undefined {\n if (!source) return undefined;\n const match = /^did:pkh:eip155:\\d+:(0x[0-9a-fA-F]{40})$/.exec(source);\n return match ? (match[1] as Address) : undefined;\n}\n\n/** @internal */\nclass MismatchError extends Error {\n override readonly name = \"MismatchError\";\n\n constructor(reason: string, details: Record<string, string>) {\n super(\n [\n reason,\n ...Object.entries(details).map(([k, v]) => ` - ${k}: ${v}`),\n ].join(\"\\n\")\n );\n }\n}\n","export const chainId = {\n mainnet: 16661,\n testnet: 16602,\n} as const;\n\nexport type ChainId = (typeof chainId)[keyof typeof chainId];\n\nconst USDC_E = \"0x1f3aa82227281ca364bfb3d253b0f1af1da6473e\";\n\n/** Chain ID → default currency. */\nexport const currency: Partial<Record<ChainId, string>> = {\n [chainId.mainnet]: USDC_E,\n};\n\n/** Default token decimals for USDC.e. */\nexport const decimals = 6;\n\n/** Default RPC URLs per chain. */\nexport const rpcUrl: Record<number, string> = {\n [chainId.mainnet]: \"https://evmrpc.0g.ai\",\n [chainId.testnet]: \"https://evmrpc-testnet.0g.ai\",\n};\n\n/** ERC-3009 ABI (`transferWithAuthorization`, `receiveWithAuthorization`). */\nexport const erc3009Abi = [\n {\n type: \"function\",\n name: \"transferWithAuthorization\",\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"v\", type: \"uint8\" },\n { name: \"r\", type: \"bytes32\" },\n { name: \"s\", type: \"bytes32\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"receiveWithAuthorization\",\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"v\", type: \"uint8\" },\n { name: \"r\", type: \"bytes32\" },\n { name: \"s\", type: \"bytes32\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"name\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"version\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n },\n] as const;\n\n/**\n * Known tokens that support ERC-3009 (TransferWithAuthorization).\n * Keyed by lowercase address for case-insensitive lookup.\n */\nexport const erc3009Tokens: Record<string, { name: string; version: string }> =\n {\n [USDC_E.toLowerCase()]: {\n name: \"Bridged USDC\",\n version: \"2\",\n },\n };\n\n/** Resolves the default currency for a given chain. */\nexport function resolveCurrency(parameters: {\n chainId?: number | undefined;\n testnet?: boolean | undefined;\n}): string {\n const id =\n parameters.chainId ??\n (parameters.testnet ? chainId.testnet : chainId.mainnet);\n const resolved = currency[id as ChainId];\n if (!resolved)\n throw new Error(`No default currency configured for chainId ${id}.`);\n return resolved;\n}\n","import { Method, z } from \"mppx\";\nimport { parseUnits } from \"viem\";\n\n/**\n * 0G charge intent for one-time ERC-20 token transfers.\n */\nexport const charge = Method.from({\n name: \"zerog\",\n intent: \"charge\",\n schema: {\n credential: {\n payload: z.discriminatedUnion(\"type\", [\n z.object({ hash: z.hash(), type: z.literal(\"hash\") }),\n z.object({\n type: z.literal(\"authorization\"),\n from: z.string(),\n to: z.string(),\n value: z.string(),\n validAfter: z.string(),\n validBefore: z.string(),\n nonce: z.string(),\n signature: z.string(),\n }),\n ]),\n },\n request: z.pipe(\n z.object({\n amount: z.amount(),\n chainId: z.optional(z.number()),\n currency: z.string(),\n decimals: z.number(),\n description: z.optional(z.string()),\n externalId: z.optional(z.string()),\n recipient: z.optional(z.string()),\n }),\n z.transform(({ amount, chainId, decimals, ...rest }) => ({\n ...rest,\n amount: parseUnits(amount, decimals).toString(),\n ...(chainId !== undefined ? { methodDetails: { chainId } } : {}),\n }))\n ),\n },\n});\n","import type { Method } from \"mppx\";\n\nimport { charge as charge_ } from \"./Charge.js\";\n\n/**\n * Creates a 0G `charge` server method.\n *\n * @example\n * ```ts\n * import { Mppx } from \"mppx/server\";\n * import { zerog } from \"@heraldprotocol/mpp/server\";\n *\n * const mppx = Mppx.create({\n * methods: [zerog({ recipient: \"0x...\", currency: \"0x...\" })],\n * });\n * ```\n */\nexport function zerog(\n parameters?: zerog.Parameters\n): readonly [Method.AnyServer] {\n return [zerog.charge(parameters)] as const;\n}\n\nexport namespace zerog {\n export type Parameters = charge_.Parameters;\n\n /** Creates a 0G `charge` method for one-time ERC-20 token transfers. */\n export const charge = charge_;\n}\n"],"mappings":"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","names":["charge","import_mppx","import_viem","chainId","decimals","charge","currency","decimals","chainId","zerog","charge"]}
@@ -0,0 +1,84 @@
1
+ import { Client, Account, Address } from 'viem';
2
+ import { Method, Store } from 'mppx';
3
+ import { M as MaybePromise } from './types-CKXzdGiJ.cjs';
4
+
5
+ /**
6
+ * Creates a 0G charge method intent for usage on the server.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { zerog } from "@heraldprotocol/mpp/server";
11
+ *
12
+ * const charge = zerog.charge({
13
+ * recipient: "0x...",
14
+ * currency: "0x...",
15
+ * account: privateKeyToAccount("0x..."),
16
+ * });
17
+ * ```
18
+ */
19
+ declare function charge(parameters?: charge.Parameters): Method.AnyServer;
20
+ declare namespace charge {
21
+ type StoreItemMap = {
22
+ [key: `mppx:charge:${string}`]: number;
23
+ };
24
+ type Parameters = {
25
+ /** Default payment amount (human-readable, e.g. "1.50"). */
26
+ amount?: string | undefined;
27
+ /** ERC-20 token contract address. */
28
+ currency?: string | undefined;
29
+ /** Token decimals. @default 6 */
30
+ decimals?: number | undefined;
31
+ /** Human-readable description. */
32
+ description?: string | undefined;
33
+ /** External identifier to echo back in receipt. */
34
+ externalId?: string | undefined;
35
+ /** Recipient address for payments. */
36
+ recipient?: string | undefined;
37
+ /** Testnet mode. */
38
+ testnet?: boolean | undefined;
39
+ /**
40
+ * Whether to wait for the charge transaction to confirm on-chain.
41
+ * @default true
42
+ */
43
+ waitForConfirmation?: boolean | undefined;
44
+ /** Function that returns a viem Client for the given chain ID. */
45
+ getClient?: ((parameters: {
46
+ chainId?: number | undefined;
47
+ }) => MaybePromise<Client>) | undefined;
48
+ /**
49
+ * Server account used to broadcast `transferWithAuthorization` transactions.
50
+ * Required when accepting `authorization` payloads. The server pays gas
51
+ * from this account.
52
+ */
53
+ account?: Account | Address | undefined;
54
+ /**
55
+ * Store for transaction hash replay protection.
56
+ *
57
+ * Use a shared store in multi-instance deployments so consumed hashes are
58
+ * visible across all server instances.
59
+ */
60
+ store?: Store.Store | undefined;
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Creates a 0G `charge` server method.
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * import { Mppx } from "mppx/server";
70
+ * import { zerog } from "@heraldprotocol/mpp/server";
71
+ *
72
+ * const mppx = Mppx.create({
73
+ * methods: [zerog({ recipient: "0x...", currency: "0x..." })],
74
+ * });
75
+ * ```
76
+ */
77
+ declare function zerog(parameters?: zerog.Parameters): readonly [Method.AnyServer];
78
+ declare namespace zerog {
79
+ type Parameters = charge.Parameters;
80
+ /** Creates a 0G `charge` method for one-time ERC-20 token transfers. */
81
+ const charge: typeof charge;
82
+ }
83
+
84
+ export { charge, zerog };
@@ -0,0 +1,3 @@
1
+ type MaybePromise<T> = T | Promise<T>;
2
+
3
+ export type { MaybePromise as M };
@@ -0,0 +1,45 @@
1
+ // src/Methods.ts
2
+ import { Method, z } from "mppx";
3
+ import { parseUnits } from "viem";
4
+ var charge = Method.from({
5
+ name: "zerog",
6
+ intent: "charge",
7
+ schema: {
8
+ credential: {
9
+ payload: z.discriminatedUnion("type", [
10
+ z.object({ hash: z.hash(), type: z.literal("hash") }),
11
+ z.object({
12
+ type: z.literal("authorization"),
13
+ from: z.string(),
14
+ to: z.string(),
15
+ value: z.string(),
16
+ validAfter: z.string(),
17
+ validBefore: z.string(),
18
+ nonce: z.string(),
19
+ signature: z.string()
20
+ })
21
+ ])
22
+ },
23
+ request: z.pipe(
24
+ z.object({
25
+ amount: z.amount(),
26
+ chainId: z.optional(z.number()),
27
+ currency: z.string(),
28
+ decimals: z.number(),
29
+ description: z.optional(z.string()),
30
+ externalId: z.optional(z.string()),
31
+ recipient: z.optional(z.string())
32
+ }),
33
+ z.transform(({ amount, chainId, decimals, ...rest }) => ({
34
+ ...rest,
35
+ amount: parseUnits(amount, decimals).toString(),
36
+ ...chainId !== void 0 ? { methodDetails: { chainId } } : {}
37
+ }))
38
+ )
39
+ }
40
+ });
41
+
42
+ export {
43
+ charge
44
+ };
45
+ //# sourceMappingURL=chunk-CRRGQQSN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/Methods.ts"],"sourcesContent":["import { Method, z } from \"mppx\";\nimport { parseUnits } from \"viem\";\n\n/**\n * 0G charge intent for one-time ERC-20 token transfers.\n */\nexport const charge = Method.from({\n name: \"zerog\",\n intent: \"charge\",\n schema: {\n credential: {\n payload: z.discriminatedUnion(\"type\", [\n z.object({ hash: z.hash(), type: z.literal(\"hash\") }),\n z.object({\n type: z.literal(\"authorization\"),\n from: z.string(),\n to: z.string(),\n value: z.string(),\n validAfter: z.string(),\n validBefore: z.string(),\n nonce: z.string(),\n signature: z.string(),\n }),\n ]),\n },\n request: z.pipe(\n z.object({\n amount: z.amount(),\n chainId: z.optional(z.number()),\n currency: z.string(),\n decimals: z.number(),\n description: z.optional(z.string()),\n externalId: z.optional(z.string()),\n recipient: z.optional(z.string()),\n }),\n z.transform(({ amount, chainId, decimals, ...rest }) => ({\n ...rest,\n amount: parseUnits(amount, decimals).toString(),\n ...(chainId !== undefined ? { methodDetails: { chainId } } : {}),\n }))\n ),\n },\n});\n"],"mappings":";AAAA,SAAS,QAAQ,SAAS;AAC1B,SAAS,kBAAkB;AAKpB,IAAM,SAAS,OAAO,KAAK;AAAA,EAChC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,IACN,YAAY;AAAA,MACV,SAAS,EAAE,mBAAmB,QAAQ;AAAA,QACpC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,QACpD,EAAE,OAAO;AAAA,UACP,MAAM,EAAE,QAAQ,eAAe;AAAA,UAC/B,MAAM,EAAE,OAAO;AAAA,UACf,IAAI,EAAE,OAAO;AAAA,UACb,OAAO,EAAE,OAAO;AAAA,UAChB,YAAY,EAAE,OAAO;AAAA,UACrB,aAAa,EAAE,OAAO;AAAA,UACtB,OAAO,EAAE,OAAO;AAAA,UAChB,WAAW,EAAE,OAAO;AAAA,QACtB,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,IACA,SAAS,EAAE;AAAA,MACT,EAAE,OAAO;AAAA,QACP,QAAQ,EAAE,OAAO;AAAA,QACjB,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,QAC9B,UAAU,EAAE,OAAO;AAAA,QACnB,UAAU,EAAE,OAAO;AAAA,QACnB,aAAa,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,QAClC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,QACjC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,MAClC,CAAC;AAAA,MACD,EAAE,UAAU,CAAC,EAAE,QAAQ,SAAS,UAAU,GAAG,KAAK,OAAO;AAAA,QACvD,GAAG;AAAA,QACH,QAAQ,WAAW,QAAQ,QAAQ,EAAE,SAAS;AAAA,QAC9C,GAAI,YAAY,SAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,CAAC;AAAA,MAChE,EAAE;AAAA,IACJ;AAAA,EACF;AACF,CAAC;","names":[]}