@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.
- package/README.md +116 -0
- package/dist/cjs/client.cjs +242 -0
- package/dist/cjs/client.cjs.map +1 -0
- package/dist/cjs/client.d.cts +112 -0
- package/dist/cjs/index.cjs +71 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +54 -0
- package/dist/cjs/server.cjs +397 -0
- package/dist/cjs/server.cjs.map +1 -0
- package/dist/cjs/server.d.cts +84 -0
- package/dist/cjs/types-CKXzdGiJ.d.cts +3 -0
- package/dist/esm/chunk-CRRGQQSN.js +45 -0
- package/dist/esm/chunk-CRRGQQSN.js.map +1 -0
- package/dist/esm/chunk-XBFBAAXJ.js +87 -0
- package/dist/esm/chunk-XBFBAAXJ.js.map +1 -0
- package/dist/esm/client.d.ts +112 -0
- package/dist/esm/client.js +150 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/index.d.ts +54 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/server.d.ts +84 -0
- package/dist/esm/server.js +260 -0
- package/dist/esm/server.js.map +1 -0
- package/dist/esm/types-CKXzdGiJ.d.ts +3 -0
- package/package.json +61 -0
- package/src/Methods.ts +43 -0
- package/src/client/Charge.ts +195 -0
- package/src/client/Methods.ts +29 -0
- package/src/client/index.ts +2 -0
- package/src/defaults.ts +100 -0
- package/src/index.ts +1 -0
- package/src/server/Charge.ts +382 -0
- package/src/server/Methods.ts +29 -0
- package/src/server/index.ts +2 -0
- package/src/types.ts +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# @heraldprotocol/mpp
|
|
2
|
+
|
|
3
|
+
0G Chain payment method for the [Machine Payments Protocol](https://mpp.dev).
|
|
4
|
+
|
|
5
|
+
> **Warning:** This package is under active development.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @heraldprotocol/mpp mppx viem
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Charge** — One-time ERC-20 token transfers. Supports push mode (client broadcasts) and pull mode (server broadcasts via ERC-3009).
|
|
16
|
+
- **0G Mainnet** — Pre-configured for USDC.e on 0G Mainnet (`16661`).
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Server
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { Mppx } from "mppx/server";
|
|
24
|
+
import { zerog } from "@heraldprotocol/mpp/server";
|
|
25
|
+
|
|
26
|
+
const mppx = Mppx.create({
|
|
27
|
+
methods: [
|
|
28
|
+
zerog.charge({
|
|
29
|
+
recipient: "0x...", // address that receives payments
|
|
30
|
+
currency: "0x...", // ERC-20 token contract address
|
|
31
|
+
}),
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Client
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { Mppx } from "mppx/client";
|
|
40
|
+
import { zerog } from "@heraldprotocol/mpp/client";
|
|
41
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
42
|
+
|
|
43
|
+
const mppx = Mppx.create({
|
|
44
|
+
methods: [
|
|
45
|
+
zerog.charge({
|
|
46
|
+
account: privateKeyToAccount("0x..."),
|
|
47
|
+
}),
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Exports
|
|
53
|
+
|
|
54
|
+
| Path | Description |
|
|
55
|
+
|------|-------------|
|
|
56
|
+
| `@heraldprotocol/mpp` | Base method definition (`charge`) |
|
|
57
|
+
| `@heraldprotocol/mpp/client` | Client-side charge with `createCredential` |
|
|
58
|
+
| `@heraldprotocol/mpp/server` | Server-side charge with `verify` |
|
|
59
|
+
|
|
60
|
+
## Client Parameters
|
|
61
|
+
|
|
62
|
+
| Parameter | Type | Description |
|
|
63
|
+
|-----------|------|-------------|
|
|
64
|
+
| `account` | `Account \| Address` | Wallet account for signing transactions |
|
|
65
|
+
| `getClient` | `(params) => Client` | Custom viem client resolver by chain ID |
|
|
66
|
+
| `mode` | `'push' \| 'pull'` | `push`: client broadcasts an ERC-20 transfer (default for JSON-RPC accounts). `pull`: client signs an ERC-3009 `TransferWithAuthorization` for the server to submit (default for local accounts) |
|
|
67
|
+
|
|
68
|
+
## Server Parameters
|
|
69
|
+
|
|
70
|
+
| Parameter | Type | Default | Description |
|
|
71
|
+
|-----------|------|---------|-------------|
|
|
72
|
+
| `recipient` | `string` | — | Address that receives payments |
|
|
73
|
+
| `currency` | `string` | USDC.e | ERC-20 token contract address |
|
|
74
|
+
| `decimals` | `number` | `6` | Token decimals |
|
|
75
|
+
| `amount` | `string` | — | Default payment amount (human-readable, e.g. "1.50") |
|
|
76
|
+
| `description` | `string` | — | Human-readable description |
|
|
77
|
+
| `externalId` | `string` | — | External identifier to echo back in receipt |
|
|
78
|
+
| `getClient` | `(params) => Client` | Built-in | Custom viem client resolver by chain ID |
|
|
79
|
+
| `testnet` | `boolean` | `false` | Use testnet chain ID (no default currency; must pass `currency`) |
|
|
80
|
+
| `waitForConfirmation` | `boolean` | `true` | Wait for on-chain confirmation before returning receipt |
|
|
81
|
+
| `account` | `Account \| Address` | — | Server wallet for broadcasting `transferWithAuthorization` transactions. Required when accepting `authorization` payloads (the server pays gas from this account). Does not need to match the recipient address |
|
|
82
|
+
| `store` | `Store` | In-memory | Store for authorization signature replay protection. Use a shared store (e.g. Redis) in multi-instance deployments so consumed signatures are visible across all server instances |
|
|
83
|
+
|
|
84
|
+
## Example
|
|
85
|
+
|
|
86
|
+
A complete Hono server and client demo is in [`example/`](./example).
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# 1. Copy the env file and fill in your private keys
|
|
90
|
+
cp example/.env.example example/.env
|
|
91
|
+
|
|
92
|
+
# 2. Start the server
|
|
93
|
+
bun run example/server.ts
|
|
94
|
+
|
|
95
|
+
# 3. In another terminal, run the client
|
|
96
|
+
bun run example/client.ts
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The server account broadcasts `transferWithAuthorization` transactions and pays gas, so it must be funded with 0G native tokens. The client account must be funded with USDC.e.
|
|
100
|
+
|
|
101
|
+
## Specification
|
|
102
|
+
|
|
103
|
+
The formal protocol specification is available at [`spec/draft-0g-charge-00.md`](./spec/draft-0g-charge-00.md).
|
|
104
|
+
|
|
105
|
+
## How It Works
|
|
106
|
+
|
|
107
|
+
1. Server issues a `402 Payment Required` challenge via `mppx` with method `zerog` and intent `charge`.
|
|
108
|
+
2. Client creates a credential based on the mode:
|
|
109
|
+
- **Push mode**: Client broadcasts an ERC-20 `transfer(to, amount)` transaction and returns the tx hash.
|
|
110
|
+
- **Pull mode**: Client signs an ERC-3009 `TransferWithAuthorization` and returns the signature. Server calls `transferWithAuthorization` to execute the transfer and pay gas.
|
|
111
|
+
3. Server verifies the payment matches the challenge (amount, recipient, currency).
|
|
112
|
+
4. Server returns a `Payment-Receipt` header on success.
|
|
113
|
+
|
|
114
|
+
## License
|
|
115
|
+
|
|
116
|
+
MIT
|
|
@@ -0,0 +1,242 @@
|
|
|
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/client/index.ts
|
|
31
|
+
var client_exports = {};
|
|
32
|
+
__export(client_exports, {
|
|
33
|
+
charge: () => charge2,
|
|
34
|
+
zerog: () => zerog
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(client_exports);
|
|
37
|
+
|
|
38
|
+
// src/client/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 rpcUrl = {
|
|
54
|
+
[chainId.mainnet]: "https://evmrpc.0g.ai",
|
|
55
|
+
[chainId.testnet]: "https://evmrpc-testnet.0g.ai"
|
|
56
|
+
};
|
|
57
|
+
var erc3009Tokens = {
|
|
58
|
+
[USDC_E.toLowerCase()]: {
|
|
59
|
+
name: "Bridged USDC",
|
|
60
|
+
version: "2"
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// src/Methods.ts
|
|
65
|
+
var import_mppx = require("mppx");
|
|
66
|
+
var import_viem = require("viem");
|
|
67
|
+
var charge = import_mppx.Method.from({
|
|
68
|
+
name: "zerog",
|
|
69
|
+
intent: "charge",
|
|
70
|
+
schema: {
|
|
71
|
+
credential: {
|
|
72
|
+
payload: import_mppx.z.discriminatedUnion("type", [
|
|
73
|
+
import_mppx.z.object({ hash: import_mppx.z.hash(), type: import_mppx.z.literal("hash") }),
|
|
74
|
+
import_mppx.z.object({
|
|
75
|
+
type: import_mppx.z.literal("authorization"),
|
|
76
|
+
from: import_mppx.z.string(),
|
|
77
|
+
to: import_mppx.z.string(),
|
|
78
|
+
value: import_mppx.z.string(),
|
|
79
|
+
validAfter: import_mppx.z.string(),
|
|
80
|
+
validBefore: import_mppx.z.string(),
|
|
81
|
+
nonce: import_mppx.z.string(),
|
|
82
|
+
signature: import_mppx.z.string()
|
|
83
|
+
})
|
|
84
|
+
])
|
|
85
|
+
},
|
|
86
|
+
request: import_mppx.z.pipe(
|
|
87
|
+
import_mppx.z.object({
|
|
88
|
+
amount: import_mppx.z.amount(),
|
|
89
|
+
chainId: import_mppx.z.optional(import_mppx.z.number()),
|
|
90
|
+
currency: import_mppx.z.string(),
|
|
91
|
+
decimals: import_mppx.z.number(),
|
|
92
|
+
description: import_mppx.z.optional(import_mppx.z.string()),
|
|
93
|
+
externalId: import_mppx.z.optional(import_mppx.z.string()),
|
|
94
|
+
recipient: import_mppx.z.optional(import_mppx.z.string())
|
|
95
|
+
}),
|
|
96
|
+
import_mppx.z.transform(({ amount, chainId: chainId2, decimals, ...rest }) => ({
|
|
97
|
+
...rest,
|
|
98
|
+
amount: (0, import_viem.parseUnits)(amount, decimals).toString(),
|
|
99
|
+
...chainId2 !== void 0 ? { methodDetails: { chainId: chainId2 } } : {}
|
|
100
|
+
}))
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// src/client/Charge.ts
|
|
106
|
+
function charge2(parameters = {}) {
|
|
107
|
+
const resolveAccount = (client, override) => {
|
|
108
|
+
const raw = override ?? parameters.account;
|
|
109
|
+
if (raw) return typeof raw === "string" ? (0, import_accounts.parseAccount)(raw) : raw;
|
|
110
|
+
if (client.account) return client.account;
|
|
111
|
+
throw new Error(
|
|
112
|
+
"No `account` provided. Pass `account` to parameters or context."
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
const resolveClient = async (chainId2) => {
|
|
116
|
+
if (parameters.getClient) return parameters.getClient({ chainId: chainId2 });
|
|
117
|
+
const id = chainId2 ?? chainId.mainnet;
|
|
118
|
+
const url = rpcUrl[id];
|
|
119
|
+
if (!url) throw new Error(`No RPC URL configured for chainId ${id}.`);
|
|
120
|
+
const { createClient, http } = await import("viem");
|
|
121
|
+
return createClient({ chain: { id }, transport: http(url) });
|
|
122
|
+
};
|
|
123
|
+
return import_mppx2.Method.toClient(charge, {
|
|
124
|
+
context: import_mppx2.z.object({
|
|
125
|
+
account: import_mppx2.z.optional(import_mppx2.z.custom()),
|
|
126
|
+
mode: import_mppx2.z.optional(import_mppx2.z.enum(["push", "pull"]))
|
|
127
|
+
}),
|
|
128
|
+
async createCredential({ challenge, context }) {
|
|
129
|
+
const chainId2 = challenge.request.methodDetails?.chainId;
|
|
130
|
+
const client = await resolveClient(chainId2);
|
|
131
|
+
const account = resolveAccount(client, context?.account);
|
|
132
|
+
const mode = context?.mode ?? parameters.mode ?? (account.type === "json-rpc" ? "push" : "pull");
|
|
133
|
+
const { request } = challenge;
|
|
134
|
+
const amount = BigInt(request.amount);
|
|
135
|
+
const currency2 = request.currency;
|
|
136
|
+
const recipient = request.recipient;
|
|
137
|
+
if (mode === "pull") {
|
|
138
|
+
const tokenMeta = erc3009Tokens[currency2.toLowerCase()];
|
|
139
|
+
if (!tokenMeta) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`Token ${currency2} does not support ERC-3009 (TransferWithAuthorization). Cannot use pull mode.`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
const resolvedChainId = chainId2 ?? client.chain?.id;
|
|
145
|
+
if (!resolvedChainId)
|
|
146
|
+
throw new Error("Could not determine chainId for EIP-712 domain.");
|
|
147
|
+
const { name: tokenName, version: tokenVersion } = tokenMeta;
|
|
148
|
+
const validAfter = 0n;
|
|
149
|
+
const validBefore = challenge.expires ? BigInt(Math.floor(new Date(challenge.expires).getTime() / 1e3)) : BigInt(Math.floor(Date.now() / 1e3) + 3600);
|
|
150
|
+
const nonce = randomNonce();
|
|
151
|
+
const signature = await (0, import_actions.signTypedData)(client, {
|
|
152
|
+
account,
|
|
153
|
+
domain: {
|
|
154
|
+
name: tokenName,
|
|
155
|
+
version: tokenVersion,
|
|
156
|
+
chainId: resolvedChainId,
|
|
157
|
+
verifyingContract: currency2
|
|
158
|
+
},
|
|
159
|
+
types: {
|
|
160
|
+
TransferWithAuthorization: [
|
|
161
|
+
{ name: "from", type: "address" },
|
|
162
|
+
{ name: "to", type: "address" },
|
|
163
|
+
{ name: "value", type: "uint256" },
|
|
164
|
+
{ name: "validAfter", type: "uint256" },
|
|
165
|
+
{ name: "validBefore", type: "uint256" },
|
|
166
|
+
{ name: "nonce", type: "bytes32" }
|
|
167
|
+
]
|
|
168
|
+
},
|
|
169
|
+
primaryType: "TransferWithAuthorization",
|
|
170
|
+
message: {
|
|
171
|
+
from: account.address,
|
|
172
|
+
to: recipient,
|
|
173
|
+
value: amount,
|
|
174
|
+
validAfter,
|
|
175
|
+
validBefore,
|
|
176
|
+
nonce
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
return import_mppx2.Credential.serialize({
|
|
180
|
+
challenge,
|
|
181
|
+
payload: {
|
|
182
|
+
type: "authorization",
|
|
183
|
+
from: account.address,
|
|
184
|
+
to: recipient,
|
|
185
|
+
value: amount.toString(),
|
|
186
|
+
validAfter: validAfter.toString(),
|
|
187
|
+
validBefore: validBefore.toString(),
|
|
188
|
+
nonce,
|
|
189
|
+
signature
|
|
190
|
+
},
|
|
191
|
+
source: `did:pkh:eip155:${resolvedChainId}:${account.address}`
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
if (mode === "push") {
|
|
195
|
+
const receipt = await (0, import_actions.sendTransactionSync)(client, {
|
|
196
|
+
account,
|
|
197
|
+
chain: client.chain,
|
|
198
|
+
to: currency2,
|
|
199
|
+
data: (0, import_viem2.encodeFunctionData)({
|
|
200
|
+
abi: import_viem2.erc20Abi,
|
|
201
|
+
functionName: "transfer",
|
|
202
|
+
args: [recipient, amount]
|
|
203
|
+
})
|
|
204
|
+
});
|
|
205
|
+
const hash = receipt.transactionHash;
|
|
206
|
+
return import_mppx2.Credential.serialize({
|
|
207
|
+
challenge,
|
|
208
|
+
payload: { hash, type: "hash" },
|
|
209
|
+
source: `did:pkh:eip155:${chainId2 ?? client.chain?.id}:${account.address}`
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
throw new Error(`Unsupported mode: ${mode}`);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
function randomNonce() {
|
|
217
|
+
const bytes = new Uint8Array(32);
|
|
218
|
+
if (typeof crypto !== "undefined") {
|
|
219
|
+
crypto.getRandomValues(bytes);
|
|
220
|
+
} else if (typeof globalThis !== "undefined" && "crypto" in globalThis) {
|
|
221
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
222
|
+
} else {
|
|
223
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
224
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return `0x${[...bytes].map((b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/client/Methods.ts
|
|
231
|
+
function zerog(parameters = {}) {
|
|
232
|
+
return [charge2(parameters)];
|
|
233
|
+
}
|
|
234
|
+
((zerog2) => {
|
|
235
|
+
zerog2.charge = charge2;
|
|
236
|
+
})(zerog || (zerog = {}));
|
|
237
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
238
|
+
0 && (module.exports = {
|
|
239
|
+
charge,
|
|
240
|
+
zerog
|
|
241
|
+
});
|
|
242
|
+
//# sourceMappingURL=client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/client/index.ts","../../src/client/Charge.ts","../../src/defaults.ts","../../src/Methods.ts","../../src/client/Methods.ts"],"sourcesContent":["export { charge } from \"./Charge.js\";\nexport { zerog } from \"./Methods.js\";\n","import type { Account, Address, Chain, Client } from \"viem\";\nimport { Credential, Method, z } from \"mppx\";\nimport { encodeFunctionData, erc20Abi } from \"viem\";\nimport { parseAccount } from \"viem/accounts\";\nimport { sendTransactionSync, signTypedData } 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 client.\n *\n * @example\n * ```ts\n * import { zerog } from \"@heraldprotocol/mpp/client\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n *\n * const charge = zerog.charge({\n * account: privateKeyToAccount(\"0x...\"),\n * });\n * ```\n */\nexport function charge(parameters: charge.Parameters = {}) {\n const resolveAccount = (\n client: Client,\n override?: Account | Address | undefined\n ): Account => {\n const raw = override ?? parameters.account;\n if (raw) return typeof raw === \"string\" ? parseAccount(raw) : raw;\n if (client.account) return client.account;\n throw new Error(\n \"No `account` provided. Pass `account` to parameters or context.\"\n );\n };\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.toClient(Methods.charge, {\n context: z.object({\n account: z.optional(z.custom<Account | Address>()),\n mode: z.optional(z.enum([\"push\", \"pull\"])),\n }),\n\n async createCredential({ challenge, context }) {\n const chainId = challenge.request.methodDetails?.chainId as\n | number\n | undefined;\n const client = await resolveClient(chainId);\n const account = resolveAccount(client, context?.account);\n\n const mode =\n context?.mode ??\n parameters.mode ??\n (account.type === \"json-rpc\" ? \"push\" : \"pull\");\n\n const { request } = challenge;\n const amount = BigInt(request.amount);\n const currency = request.currency as Address;\n const recipient = request.recipient as Address;\n\n if (mode === \"pull\") {\n const tokenMeta = defaults.erc3009Tokens[currency.toLowerCase()];\n if (!tokenMeta) {\n throw new Error(\n `Token ${currency} does not support ERC-3009 (TransferWithAuthorization). ` +\n `Cannot use pull mode.`\n );\n }\n\n const resolvedChainId = chainId ?? client.chain?.id;\n if (!resolvedChainId)\n throw new Error(\"Could not determine chainId for EIP-712 domain.\");\n\n const { name: tokenName, version: tokenVersion } = tokenMeta;\n\n const validAfter = 0n;\n const validBefore = challenge.expires\n ? BigInt(Math.floor(new Date(challenge.expires).getTime() / 1000))\n : BigInt(Math.floor(Date.now() / 1000) + 3600); // 1 hour default\n const nonce = randomNonce();\n\n const signature = await signTypedData(client, {\n account,\n domain: {\n name: tokenName,\n version: tokenVersion,\n chainId: resolvedChainId,\n verifyingContract: currency,\n },\n types: {\n TransferWithAuthorization: [\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 ],\n },\n primaryType: \"TransferWithAuthorization\",\n message: {\n from: account.address,\n to: recipient,\n value: amount,\n validAfter,\n validBefore,\n nonce,\n },\n });\n\n return Credential.serialize({\n challenge,\n payload: {\n type: \"authorization\" as const,\n from: account.address,\n to: recipient,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n signature,\n },\n source: `did:pkh:eip155:${resolvedChainId}:${account.address}`,\n });\n }\n\n if (mode === \"push\") {\n const receipt = await sendTransactionSync(client, {\n account,\n chain: client.chain,\n to: currency,\n data: encodeFunctionData({\n abi: erc20Abi,\n functionName: \"transfer\",\n args: [recipient, amount],\n }),\n });\n const hash = receipt.transactionHash;\n return Credential.serialize({\n challenge,\n payload: { hash, type: \"hash\" },\n source: `did:pkh:eip155:${chainId ?? client.chain?.id}:${account.address}`,\n });\n }\n\n throw new Error(`Unsupported mode: ${mode}`);\n },\n });\n}\n\nexport declare namespace charge {\n type Parameters = {\n /** Account to use for signing. */\n account?: Account | Address | 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 * Controls how the charge transaction is submitted.\n *\n * - `'push'`: Client broadcasts the transaction and sends the tx hash.\n * - `'pull'`: Client signs an ERC-3009 TransferWithAuthorization\n * message. Server calls `transferWithAuthorization` and pays gas.\n *\n * @default `'push'` for JSON-RPC accounts, `'pull'` for local accounts.\n */\n mode?: \"push\" | \"pull\" | undefined;\n };\n}\n\n/** Generates a random 32-byte hex nonce. */\nfunction randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32);\n if (typeof crypto !== \"undefined\") {\n crypto.getRandomValues(bytes);\n } else if (typeof globalThis !== \"undefined\" && \"crypto\" in globalThis) {\n (globalThis as unknown as { crypto: Crypto }).crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n return `0x${[...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\")}`;\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` client method.\n *\n * @example\n * ```ts\n * import { Mppx } from \"mppx/client\";\n * import { zerog } from \"@heraldprotocol/mpp/client\";\n *\n * const mppx = Mppx.create({\n * methods: [zerog({ account })],\n * });\n * ```\n */\nexport function zerog(\n parameters: zerog.Parameters = {}\n): readonly [Method.AnyClient] {\n return [charge_(parameters)] as const;\n}\n\nexport namespace zerog {\n export type Parameters = charge_.Parameters;\n\n /** Creates a 0G `charge` client 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","charge","chainId","currency","charge","zerog"]}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Account, Address, Client } from 'viem';
|
|
2
|
+
import { Method, z } from 'mppx';
|
|
3
|
+
import { M as MaybePromise } from './types-CKXzdGiJ.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a 0G charge method intent for usage on the client.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { zerog } from "@heraldprotocol/mpp/client";
|
|
11
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
12
|
+
*
|
|
13
|
+
* const charge = zerog.charge({
|
|
14
|
+
* account: privateKeyToAccount("0x..."),
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
declare function charge(parameters?: charge.Parameters): Method.Client<{
|
|
19
|
+
readonly name: "zerog";
|
|
20
|
+
readonly intent: "charge";
|
|
21
|
+
readonly schema: {
|
|
22
|
+
readonly credential: {
|
|
23
|
+
readonly payload: z.ZodMiniDiscriminatedUnion<[z.ZodMiniObject<{
|
|
24
|
+
hash: z.ZodMiniString<string>;
|
|
25
|
+
type: z.ZodMiniLiteral<"hash">;
|
|
26
|
+
}, z.core.$strip>, z.ZodMiniObject<{
|
|
27
|
+
type: z.ZodMiniLiteral<"authorization">;
|
|
28
|
+
from: z.ZodMiniString<string>;
|
|
29
|
+
to: z.ZodMiniString<string>;
|
|
30
|
+
value: z.ZodMiniString<string>;
|
|
31
|
+
validAfter: z.ZodMiniString<string>;
|
|
32
|
+
validBefore: z.ZodMiniString<string>;
|
|
33
|
+
nonce: z.ZodMiniString<string>;
|
|
34
|
+
signature: z.ZodMiniString<string>;
|
|
35
|
+
}, z.core.$strip>], "type">;
|
|
36
|
+
};
|
|
37
|
+
readonly request: z.ZodMiniPipe<z.ZodMiniObject<{
|
|
38
|
+
amount: z.ZodMiniString<string>;
|
|
39
|
+
chainId: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
40
|
+
currency: z.ZodMiniString<string>;
|
|
41
|
+
decimals: z.ZodMiniNumber<number>;
|
|
42
|
+
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
43
|
+
externalId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
44
|
+
recipient: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
45
|
+
}, z.core.$strip>, z.ZodMiniTransform<{
|
|
46
|
+
methodDetails?: {
|
|
47
|
+
chainId: number;
|
|
48
|
+
} | undefined;
|
|
49
|
+
amount: string;
|
|
50
|
+
currency: string;
|
|
51
|
+
description?: string | undefined;
|
|
52
|
+
externalId?: string | undefined;
|
|
53
|
+
recipient?: string | undefined;
|
|
54
|
+
}, {
|
|
55
|
+
amount: string;
|
|
56
|
+
currency: string;
|
|
57
|
+
decimals: number;
|
|
58
|
+
chainId?: number | undefined;
|
|
59
|
+
description?: string | undefined;
|
|
60
|
+
externalId?: string | undefined;
|
|
61
|
+
recipient?: string | undefined;
|
|
62
|
+
}>>;
|
|
63
|
+
};
|
|
64
|
+
}, z.ZodMiniObject<{
|
|
65
|
+
account: z.ZodMiniOptional<z.ZodMiniCustom<`0x${string}` | Account, `0x${string}` | Account>>;
|
|
66
|
+
mode: z.ZodMiniOptional<z.ZodMiniEnum<{
|
|
67
|
+
push: "push";
|
|
68
|
+
pull: "pull";
|
|
69
|
+
}>>;
|
|
70
|
+
}, z.core.$strip>>;
|
|
71
|
+
declare namespace charge {
|
|
72
|
+
type Parameters = {
|
|
73
|
+
/** Account to use for signing. */
|
|
74
|
+
account?: Account | Address | undefined;
|
|
75
|
+
/** Function that returns a viem Client for the given chain ID. */
|
|
76
|
+
getClient?: ((parameters: {
|
|
77
|
+
chainId?: number | undefined;
|
|
78
|
+
}) => MaybePromise<Client>) | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Controls how the charge transaction is submitted.
|
|
81
|
+
*
|
|
82
|
+
* - `'push'`: Client broadcasts the transaction and sends the tx hash.
|
|
83
|
+
* - `'pull'`: Client signs an ERC-3009 TransferWithAuthorization
|
|
84
|
+
* message. Server calls `transferWithAuthorization` and pays gas.
|
|
85
|
+
*
|
|
86
|
+
* @default `'push'` for JSON-RPC accounts, `'pull'` for local accounts.
|
|
87
|
+
*/
|
|
88
|
+
mode?: "push" | "pull" | undefined;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Creates a 0G `charge` client method.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* import { Mppx } from "mppx/client";
|
|
98
|
+
* import { zerog } from "@heraldprotocol/mpp/client";
|
|
99
|
+
*
|
|
100
|
+
* const mppx = Mppx.create({
|
|
101
|
+
* methods: [zerog({ account })],
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
declare function zerog(parameters?: zerog.Parameters): readonly [Method.AnyClient];
|
|
106
|
+
declare namespace zerog {
|
|
107
|
+
type Parameters = charge.Parameters;
|
|
108
|
+
/** Creates a 0G `charge` client method for one-time ERC-20 token transfers. */
|
|
109
|
+
const charge: typeof charge;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { charge, zerog };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
charge: () => charge
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
|
|
27
|
+
// src/Methods.ts
|
|
28
|
+
var import_mppx = require("mppx");
|
|
29
|
+
var import_viem = require("viem");
|
|
30
|
+
var charge = import_mppx.Method.from({
|
|
31
|
+
name: "zerog",
|
|
32
|
+
intent: "charge",
|
|
33
|
+
schema: {
|
|
34
|
+
credential: {
|
|
35
|
+
payload: import_mppx.z.discriminatedUnion("type", [
|
|
36
|
+
import_mppx.z.object({ hash: import_mppx.z.hash(), type: import_mppx.z.literal("hash") }),
|
|
37
|
+
import_mppx.z.object({
|
|
38
|
+
type: import_mppx.z.literal("authorization"),
|
|
39
|
+
from: import_mppx.z.string(),
|
|
40
|
+
to: import_mppx.z.string(),
|
|
41
|
+
value: import_mppx.z.string(),
|
|
42
|
+
validAfter: import_mppx.z.string(),
|
|
43
|
+
validBefore: import_mppx.z.string(),
|
|
44
|
+
nonce: import_mppx.z.string(),
|
|
45
|
+
signature: import_mppx.z.string()
|
|
46
|
+
})
|
|
47
|
+
])
|
|
48
|
+
},
|
|
49
|
+
request: import_mppx.z.pipe(
|
|
50
|
+
import_mppx.z.object({
|
|
51
|
+
amount: import_mppx.z.amount(),
|
|
52
|
+
chainId: import_mppx.z.optional(import_mppx.z.number()),
|
|
53
|
+
currency: import_mppx.z.string(),
|
|
54
|
+
decimals: import_mppx.z.number(),
|
|
55
|
+
description: import_mppx.z.optional(import_mppx.z.string()),
|
|
56
|
+
externalId: import_mppx.z.optional(import_mppx.z.string()),
|
|
57
|
+
recipient: import_mppx.z.optional(import_mppx.z.string())
|
|
58
|
+
}),
|
|
59
|
+
import_mppx.z.transform(({ amount, chainId, decimals, ...rest }) => ({
|
|
60
|
+
...rest,
|
|
61
|
+
amount: (0, import_viem.parseUnits)(amount, decimals).toString(),
|
|
62
|
+
...chainId !== void 0 ? { methodDetails: { chainId } } : {}
|
|
63
|
+
}))
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
68
|
+
0 && (module.exports = {
|
|
69
|
+
charge
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Methods.ts"],"sourcesContent":["export { charge } from \"./Methods.js\";\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAA0B;AAC1B,kBAA2B;AAKpB,IAAM,SAAS,mBAAO,KAAK;AAAA,EAChC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,IACN,YAAY;AAAA,MACV,SAAS,cAAE,mBAAmB,QAAQ;AAAA,QACpC,cAAE,OAAO,EAAE,MAAM,cAAE,KAAK,GAAG,MAAM,cAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,QACpD,cAAE,OAAO;AAAA,UACP,MAAM,cAAE,QAAQ,eAAe;AAAA,UAC/B,MAAM,cAAE,OAAO;AAAA,UACf,IAAI,cAAE,OAAO;AAAA,UACb,OAAO,cAAE,OAAO;AAAA,UAChB,YAAY,cAAE,OAAO;AAAA,UACrB,aAAa,cAAE,OAAO;AAAA,UACtB,OAAO,cAAE,OAAO;AAAA,UAChB,WAAW,cAAE,OAAO;AAAA,QACtB,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,IACA,SAAS,cAAE;AAAA,MACT,cAAE,OAAO;AAAA,QACP,QAAQ,cAAE,OAAO;AAAA,QACjB,SAAS,cAAE,SAAS,cAAE,OAAO,CAAC;AAAA,QAC9B,UAAU,cAAE,OAAO;AAAA,QACnB,UAAU,cAAE,OAAO;AAAA,QACnB,aAAa,cAAE,SAAS,cAAE,OAAO,CAAC;AAAA,QAClC,YAAY,cAAE,SAAS,cAAE,OAAO,CAAC;AAAA,QACjC,WAAW,cAAE,SAAS,cAAE,OAAO,CAAC;AAAA,MAClC,CAAC;AAAA,MACD,cAAE,UAAU,CAAC,EAAE,QAAQ,SAAS,UAAU,GAAG,KAAK,OAAO;AAAA,QACvD,GAAG;AAAA,QACH,YAAQ,wBAAW,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":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from 'mppx';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 0G charge intent for one-time ERC-20 token transfers.
|
|
5
|
+
*/
|
|
6
|
+
declare const charge: {
|
|
7
|
+
readonly name: "zerog";
|
|
8
|
+
readonly intent: "charge";
|
|
9
|
+
readonly schema: {
|
|
10
|
+
readonly credential: {
|
|
11
|
+
readonly payload: z.ZodMiniDiscriminatedUnion<[z.ZodMiniObject<{
|
|
12
|
+
hash: z.ZodMiniString<string>;
|
|
13
|
+
type: z.ZodMiniLiteral<"hash">;
|
|
14
|
+
}, z.core.$strip>, z.ZodMiniObject<{
|
|
15
|
+
type: z.ZodMiniLiteral<"authorization">;
|
|
16
|
+
from: z.ZodMiniString<string>;
|
|
17
|
+
to: z.ZodMiniString<string>;
|
|
18
|
+
value: z.ZodMiniString<string>;
|
|
19
|
+
validAfter: z.ZodMiniString<string>;
|
|
20
|
+
validBefore: z.ZodMiniString<string>;
|
|
21
|
+
nonce: z.ZodMiniString<string>;
|
|
22
|
+
signature: z.ZodMiniString<string>;
|
|
23
|
+
}, z.core.$strip>], "type">;
|
|
24
|
+
};
|
|
25
|
+
readonly request: z.ZodMiniPipe<z.ZodMiniObject<{
|
|
26
|
+
amount: z.ZodMiniString<string>;
|
|
27
|
+
chainId: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
28
|
+
currency: z.ZodMiniString<string>;
|
|
29
|
+
decimals: z.ZodMiniNumber<number>;
|
|
30
|
+
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
31
|
+
externalId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
32
|
+
recipient: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
33
|
+
}, z.core.$strip>, z.ZodMiniTransform<{
|
|
34
|
+
methodDetails?: {
|
|
35
|
+
chainId: number;
|
|
36
|
+
} | undefined;
|
|
37
|
+
amount: string;
|
|
38
|
+
currency: string;
|
|
39
|
+
description?: string | undefined;
|
|
40
|
+
externalId?: string | undefined;
|
|
41
|
+
recipient?: string | undefined;
|
|
42
|
+
}, {
|
|
43
|
+
amount: string;
|
|
44
|
+
currency: string;
|
|
45
|
+
decimals: number;
|
|
46
|
+
chainId?: number | undefined;
|
|
47
|
+
description?: string | undefined;
|
|
48
|
+
externalId?: string | undefined;
|
|
49
|
+
recipient?: string | undefined;
|
|
50
|
+
}>>;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export { charge };
|