@armory-sh/base 0.2.0 → 0.2.2
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/dist/encoding/x402.d.ts +85 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.js +378 -44
- package/dist/types/x402.d.ts +136 -0
- package/dist/utils/x402.d.ts +56 -0
- package/dist/validation.test.d.ts +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X402 Protocol Encoding - Coinbase Compatible
|
|
3
|
+
*
|
|
4
|
+
* All payment payloads are Base64 encoded for transport in HTTP headers.
|
|
5
|
+
* This matches the Coinbase x402 SDK format.
|
|
6
|
+
*/
|
|
7
|
+
import type { PaymentPayload, SettlementResponse, X402Response, LegacyPaymentPayload, PaymentPayloadV1, PaymentPayloadV2, PaymentRequirements } from "../types/x402";
|
|
8
|
+
/**
|
|
9
|
+
* Safe Base64 encode (URL-safe, no padding)
|
|
10
|
+
*/
|
|
11
|
+
export declare function safeBase64Encode(str: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Safe Base64 decode (handles URL-safe format)
|
|
14
|
+
*/
|
|
15
|
+
export declare function safeBase64Decode(str: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Encode payment payload to Base64 string
|
|
18
|
+
* All versions use Base64 encoding for compatibility
|
|
19
|
+
*/
|
|
20
|
+
export declare function encodePayment(payload: PaymentPayload | LegacyPaymentPayload): string;
|
|
21
|
+
/**
|
|
22
|
+
* Decode payment payload from Base64 string
|
|
23
|
+
*/
|
|
24
|
+
export declare function decodePayment(encoded: string): PaymentPayload;
|
|
25
|
+
/**
|
|
26
|
+
* Encode settlement response to Base64 string
|
|
27
|
+
*/
|
|
28
|
+
export declare function encodeSettlementResponse(response: SettlementResponse): string;
|
|
29
|
+
/**
|
|
30
|
+
* Decode settlement response from Base64 string
|
|
31
|
+
*/
|
|
32
|
+
export declare function decodeSettlementResponse(encoded: string): SettlementResponse;
|
|
33
|
+
/**
|
|
34
|
+
* Encode X402 error response
|
|
35
|
+
*/
|
|
36
|
+
export declare function encodeX402Response(response: X402Response): string;
|
|
37
|
+
/**
|
|
38
|
+
* Decode X402 error response
|
|
39
|
+
*/
|
|
40
|
+
export declare function decodeX402Response(encoded: string): X402Response;
|
|
41
|
+
/**
|
|
42
|
+
* Unified X402 headers - Coinbase compatible
|
|
43
|
+
*/
|
|
44
|
+
export declare const X402_HEADERS: {
|
|
45
|
+
readonly PAYMENT: "X-PAYMENT";
|
|
46
|
+
readonly PAYMENT_RESPONSE: "X-PAYMENT-RESPONSE";
|
|
47
|
+
readonly PAYMENT_REQUIRED: "X-PAYMENT-REQUIRED";
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Detect payment version from headers
|
|
51
|
+
* Returns null if no payment header found
|
|
52
|
+
*
|
|
53
|
+
* Supports both x402 format (X-PAYMENT header with x402Version)
|
|
54
|
+
* and legacy format (X-PAYMENT for v1, PAYMENT-SIGNATURE for v2)
|
|
55
|
+
*/
|
|
56
|
+
export declare function detectPaymentVersion(headers: Headers): number | null;
|
|
57
|
+
/**
|
|
58
|
+
* Extract payment from headers
|
|
59
|
+
*/
|
|
60
|
+
export declare function extractPaymentFromHeaders(headers: Headers): PaymentPayload | null;
|
|
61
|
+
/**
|
|
62
|
+
* Create payment required headers
|
|
63
|
+
*/
|
|
64
|
+
export declare function createPaymentRequiredHeaders(requirements: PaymentRequirements | PaymentRequirements[]): Record<string, string>;
|
|
65
|
+
/**
|
|
66
|
+
* Create settlement response headers
|
|
67
|
+
*/
|
|
68
|
+
export declare function createSettlementHeaders(settlement: SettlementResponse): Record<string, string>;
|
|
69
|
+
export declare const encodePaymentV1: typeof encodePayment;
|
|
70
|
+
export declare const decodePaymentV1: typeof decodePayment;
|
|
71
|
+
export declare const encodePaymentV2: typeof encodePayment;
|
|
72
|
+
export declare const decodePaymentV2: typeof decodePayment;
|
|
73
|
+
export declare const encodeSettlementV1: typeof encodeSettlementResponse;
|
|
74
|
+
export declare const decodeSettlementV1: typeof decodeSettlementResponse;
|
|
75
|
+
export declare const encodeSettlementV2: typeof encodeSettlementResponse;
|
|
76
|
+
export declare const decodeSettlementV2: typeof decodeSettlementResponse;
|
|
77
|
+
/**
|
|
78
|
+
* Type guards for legacy compatibility
|
|
79
|
+
*/
|
|
80
|
+
export declare function isLegacyV1(payload: unknown): payload is PaymentPayloadV1;
|
|
81
|
+
export declare function isLegacyV2(payload: unknown): payload is PaymentPayloadV2;
|
|
82
|
+
/**
|
|
83
|
+
* Decode settlement from headers (legacy compatibility)
|
|
84
|
+
*/
|
|
85
|
+
export declare function decodeSettlement(headers: Headers): SettlementResponse;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
export type { Address as X402Address, Hex, X402Version, Scheme, Network as X402Network, ExactEvmAuthorization, ExactEvmPayload, PaymentPayload as X402PaymentPayload, UnsignedPaymentPayload as X402UnsignedPaymentPayload, PaymentRequirements as X402PaymentRequirements, SettlementResponse as X402SettlementResponse, VerifyResponse, X402Response, PaymentPayloadV1 as X402PayloadV1, PaymentPayloadV2 as X402PayloadV2, LegacyPaymentPayload as X402LegacyPayload, } from "./types/x402";
|
|
2
|
+
export { X402_VERSION, SCHEMES, isPaymentPayload, isExactEvmPayload, legacyToPaymentPayload, } from "./types/x402";
|
|
3
|
+
export { safeBase64Encode, safeBase64Decode, encodePayment, decodePayment, encodeSettlementResponse, decodeSettlementResponse, encodeX402Response, decodeX402Response, X402_HEADERS, detectPaymentVersion, extractPaymentFromHeaders, createPaymentRequiredHeaders, createSettlementHeaders, isLegacyV1, isLegacyV2, } from "./encoding/x402";
|
|
4
|
+
export { createNonce, toAtomicUnits, fromAtomicUnits, parseSignature, combineSignature, caip2ToNetwork, networkToCaip2, getCurrentTimestamp, isValidAddress, normalizeAddress, } from "./utils/x402";
|
|
1
5
|
export type { PaymentPayloadV1, PaymentRequirementsV1, SettlementResponseV1, } from "./types/v1";
|
|
2
|
-
export { V1_HEADERS, encodePaymentPayload, decodePaymentPayload, encodeSettlementResponse, decodeSettlementResponse, } from "./types/v1";
|
|
6
|
+
export { V1_HEADERS, encodePaymentPayload, decodePaymentPayload, encodeSettlementResponse as encodeSettlementResponseV1, decodeSettlementResponse as decodeSettlementResponseV1, } from "./types/v1";
|
|
3
7
|
export type { CAIP2ChainId, CAIPAssetId, Address, Signature, PayToV2, Extensions, PaymentPayloadV2, PaymentRequirementsV2, SettlementResponseV2, } from "./types/v2";
|
|
4
8
|
export { V2_HEADERS, isCAIP2ChainId, isCAIPAssetId, isAddress, } from "./types/v2";
|
|
5
9
|
export type { PaymentPayload, PaymentRequirements, SettlementResponse, } from "./types/protocol";
|
|
6
|
-
export { isV1, isV2, getPaymentVersion
|
|
10
|
+
export { isV1, isV2, getPaymentVersion, getRequirementsVersion, getSettlementVersion, getPaymentHeaderName, getPaymentResponseHeaderName, getPaymentRequiredHeaderName, isSettlementSuccessful, getTxHash, } from "./types/protocol";
|
|
7
11
|
export type { NetworkConfig, CustomToken } from "./types/networks";
|
|
8
12
|
export { NETWORKS, getNetworkConfig, getNetworkByChainId, getMainnets, getTestnets, registerToken, getCustomToken, getAllCustomTokens, unregisterToken, isCustomToken, } from "./types/networks";
|
|
9
13
|
export type { TransferWithAuthorizationParams, ReceiveWithAuthorizationParams, BalanceOfParams, BalanceOfReturnType, NameReturnType, SymbolReturnType, ERC20Abi, } from "./abi/erc20";
|
|
10
14
|
export { ERC20_ABI } from "./abi/erc20";
|
|
11
|
-
export type { PaymentPayload as EncodingPaymentPayload, SettlementResponse as EncodingSettlementResponse, } from "./encoding";
|
|
12
|
-
export { encodePaymentV1, decodePaymentV1, encodeSettlementV1, decodeSettlementV1, encodePaymentV2, decodePaymentV2, encodeSettlementV2, decodeSettlementV2, detectPaymentVersion, decodePayment, decodeSettlement, isPaymentV1, isPaymentV2, isSettlementV1, isSettlementV2, } from "./encoding";
|
|
13
15
|
export type { TypedDataDomain, EIP712Domain, TransferWithAuthorization, TypedDataField, EIP712Types, } from "./eip712";
|
|
14
16
|
export { EIP712_TYPES, USDC_DOMAIN, createEIP712Domain, createTransferWithAuthorization, validateTransferWithAuthorization, } from "./eip712";
|
|
15
17
|
export { resolveNetwork, resolveToken, resolveFacilitator, checkFacilitatorSupport, validatePaymentConfig, validateAcceptConfig, getAvailableNetworks, getAvailableTokens, isValidationError, isResolvedNetwork, isResolvedToken, createError, } from "./validation";
|
|
18
|
+
export { encodePaymentV1, decodePaymentV1, encodeSettlementV1, decodeSettlementV1, encodePaymentV2, decodePaymentV2, encodeSettlementV2, decodeSettlementV2, detectPaymentVersion as detectPaymentVersionLegacy, decodePayment as decodePaymentLegacy, decodeSettlement as decodeSettlementLegacy, isPaymentV1, isPaymentV2, isSettlementV1, isSettlementV2, } from "./encoding";
|
|
16
19
|
export type { NetworkId, TokenId, FacilitatorConfig, AcceptPaymentOptions, PaymentResult, PaymentError, PaymentErrorCode, ArmoryPaymentResult, ResolvedNetwork, ResolvedToken, ResolvedFacilitator, ResolvedPaymentConfig, ValidationError, } from "./types/simple";
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,307 @@
|
|
|
1
|
+
// src/types/x402.ts
|
|
2
|
+
var X402_VERSION = 1;
|
|
3
|
+
var SCHEMES = ["exact"];
|
|
4
|
+
var CHAIN_ID_TO_NETWORK = {
|
|
5
|
+
1: "ethereum",
|
|
6
|
+
8453: "base",
|
|
7
|
+
84532: "base-sepolia",
|
|
8
|
+
137: "polygon",
|
|
9
|
+
42161: "arbitrum",
|
|
10
|
+
421614: "arbitrum-sepolia",
|
|
11
|
+
10: "optimism",
|
|
12
|
+
11155420: "optimism-sepolia",
|
|
13
|
+
11155111: "ethereum-sepolia"
|
|
14
|
+
};
|
|
15
|
+
function isPaymentPayload(obj) {
|
|
16
|
+
return typeof obj === "object" && obj !== null && "x402Version" in obj && "scheme" in obj && "network" in obj && "payload" in obj;
|
|
17
|
+
}
|
|
18
|
+
function isExactEvmPayload(obj) {
|
|
19
|
+
return typeof obj === "object" && obj !== null && "signature" in obj && "authorization" in obj;
|
|
20
|
+
}
|
|
21
|
+
function extractNetworkFromLegacy(legacy) {
|
|
22
|
+
if ("network" in legacy && typeof legacy.network === "string") {
|
|
23
|
+
return legacy.network;
|
|
24
|
+
}
|
|
25
|
+
if ("chainId" in legacy && typeof legacy.chainId === "string") {
|
|
26
|
+
const match = legacy.chainId.match(/^eip155:(\d+)$/);
|
|
27
|
+
if (match) {
|
|
28
|
+
const chainId = parseInt(match[1], 10);
|
|
29
|
+
return CHAIN_ID_TO_NETWORK[chainId] || `eip155:${chainId}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if ("chainId" in legacy && typeof legacy.chainId === "number") {
|
|
33
|
+
return CHAIN_ID_TO_NETWORK[legacy.chainId] || `eip155:${legacy.chainId}`;
|
|
34
|
+
}
|
|
35
|
+
return "base";
|
|
36
|
+
}
|
|
37
|
+
function extractSignatureFromLegacy(legacy) {
|
|
38
|
+
if ("v" in legacy && "r" in legacy && "s" in legacy) {
|
|
39
|
+
const v = legacy.v.toString(16).padStart(2, "0");
|
|
40
|
+
const r = legacy.r.startsWith("0x") ? legacy.r.slice(2) : legacy.r;
|
|
41
|
+
const s = legacy.s.startsWith("0x") ? legacy.s.slice(2) : legacy.s;
|
|
42
|
+
return `0x${r}${s}${v}`;
|
|
43
|
+
}
|
|
44
|
+
if ("signature" in legacy && typeof legacy.signature === "object" && legacy.signature !== null) {
|
|
45
|
+
const sig = legacy.signature;
|
|
46
|
+
const v = sig.v.toString(16).padStart(2, "0");
|
|
47
|
+
const r = sig.r.startsWith("0x") ? sig.r.slice(2) : sig.r;
|
|
48
|
+
const s = sig.s.startsWith("0x") ? sig.s.slice(2) : sig.s;
|
|
49
|
+
return `0x${r}${s}${v}`;
|
|
50
|
+
}
|
|
51
|
+
return "0x";
|
|
52
|
+
}
|
|
53
|
+
function convertAmountToAtomic(amount) {
|
|
54
|
+
if (amount.includes(".")) {
|
|
55
|
+
const parts = amount.split(".");
|
|
56
|
+
const whole = parts[0];
|
|
57
|
+
const fractional = parts[1] || "";
|
|
58
|
+
const paddedFractional = fractional.padEnd(6, "0").slice(0, 6);
|
|
59
|
+
return `${whole}${paddedFractional}`;
|
|
60
|
+
}
|
|
61
|
+
return amount;
|
|
62
|
+
}
|
|
63
|
+
function convertNonceToHex(nonce) {
|
|
64
|
+
if (nonce.startsWith("0x") && nonce.length === 66) {
|
|
65
|
+
return nonce;
|
|
66
|
+
}
|
|
67
|
+
const hex = BigInt(nonce).toString(16).padStart(64, "0");
|
|
68
|
+
return `0x${hex}`;
|
|
69
|
+
}
|
|
70
|
+
function extractFromAddress(legacy) {
|
|
71
|
+
return legacy.from;
|
|
72
|
+
}
|
|
73
|
+
function extractToAddress(legacy) {
|
|
74
|
+
if ("to" in legacy && typeof legacy.to === "string") {
|
|
75
|
+
return legacy.to;
|
|
76
|
+
}
|
|
77
|
+
return legacy.from;
|
|
78
|
+
}
|
|
79
|
+
function legacyToPaymentPayload(legacy) {
|
|
80
|
+
if (isPaymentPayload(legacy)) {
|
|
81
|
+
return legacy;
|
|
82
|
+
}
|
|
83
|
+
const network = extractNetworkFromLegacy(legacy);
|
|
84
|
+
const signature = extractSignatureFromLegacy(legacy);
|
|
85
|
+
const value = convertAmountToAtomic(legacy.amount);
|
|
86
|
+
const nonce = convertNonceToHex(legacy.nonce);
|
|
87
|
+
const from = extractFromAddress(legacy);
|
|
88
|
+
const to = extractToAddress(legacy);
|
|
89
|
+
return {
|
|
90
|
+
x402Version: X402_VERSION,
|
|
91
|
+
scheme: "exact",
|
|
92
|
+
network,
|
|
93
|
+
payload: {
|
|
94
|
+
signature,
|
|
95
|
+
authorization: {
|
|
96
|
+
from,
|
|
97
|
+
to,
|
|
98
|
+
value,
|
|
99
|
+
validAfter: "0",
|
|
100
|
+
validBefore: legacy.expiry.toString(),
|
|
101
|
+
nonce
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/encoding/x402.ts
|
|
108
|
+
function safeBase64Encode(str) {
|
|
109
|
+
return Buffer.from(str).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
110
|
+
}
|
|
111
|
+
function safeBase64Decode(str) {
|
|
112
|
+
const padding = 4 - str.length % 4;
|
|
113
|
+
if (padding !== 4) {
|
|
114
|
+
str += "=".repeat(padding);
|
|
115
|
+
}
|
|
116
|
+
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
117
|
+
return Buffer.from(str, "base64").toString("utf-8");
|
|
118
|
+
}
|
|
119
|
+
function encodePayment(payload) {
|
|
120
|
+
let normalizedPayload;
|
|
121
|
+
if (isPaymentPayload(payload)) {
|
|
122
|
+
normalizedPayload = payload;
|
|
123
|
+
} else {
|
|
124
|
+
normalizedPayload = legacyToPaymentPayload(payload);
|
|
125
|
+
}
|
|
126
|
+
const safePayload = JSON.parse(JSON.stringify(normalizedPayload, (_, value) => {
|
|
127
|
+
if (typeof value === "bigint") {
|
|
128
|
+
return value.toString();
|
|
129
|
+
}
|
|
130
|
+
return value;
|
|
131
|
+
}));
|
|
132
|
+
return safeBase64Encode(JSON.stringify(safePayload));
|
|
133
|
+
}
|
|
134
|
+
function decodePayment(encoded) {
|
|
135
|
+
const decoded = safeBase64Decode(encoded);
|
|
136
|
+
const parsed = JSON.parse(decoded);
|
|
137
|
+
if (!isPaymentPayload(parsed)) {
|
|
138
|
+
return legacyToPaymentPayload(parsed);
|
|
139
|
+
}
|
|
140
|
+
return parsed;
|
|
141
|
+
}
|
|
142
|
+
function encodeSettlementResponse(response) {
|
|
143
|
+
const safeResponse = JSON.parse(JSON.stringify(response, (_, value) => {
|
|
144
|
+
if (typeof value === "bigint") {
|
|
145
|
+
return value.toString();
|
|
146
|
+
}
|
|
147
|
+
return value;
|
|
148
|
+
}));
|
|
149
|
+
return safeBase64Encode(JSON.stringify(safeResponse));
|
|
150
|
+
}
|
|
151
|
+
function decodeSettlementResponse(encoded) {
|
|
152
|
+
const decoded = safeBase64Decode(encoded);
|
|
153
|
+
return JSON.parse(decoded);
|
|
154
|
+
}
|
|
155
|
+
function encodeX402Response(response) {
|
|
156
|
+
return safeBase64Encode(JSON.stringify(response));
|
|
157
|
+
}
|
|
158
|
+
function decodeX402Response(encoded) {
|
|
159
|
+
const decoded = safeBase64Decode(encoded);
|
|
160
|
+
return JSON.parse(decoded);
|
|
161
|
+
}
|
|
162
|
+
var X402_HEADERS = {
|
|
163
|
+
PAYMENT: "X-PAYMENT",
|
|
164
|
+
PAYMENT_RESPONSE: "X-PAYMENT-RESPONSE",
|
|
165
|
+
PAYMENT_REQUIRED: "X-PAYMENT-REQUIRED"
|
|
166
|
+
};
|
|
167
|
+
function detectPaymentVersion(headers) {
|
|
168
|
+
if (headers.has("PAYMENT-SIGNATURE")) {
|
|
169
|
+
return 2;
|
|
170
|
+
}
|
|
171
|
+
if (headers.has(X402_HEADERS.PAYMENT)) {
|
|
172
|
+
const encoded = headers.get(X402_HEADERS.PAYMENT);
|
|
173
|
+
if (encoded) {
|
|
174
|
+
try {
|
|
175
|
+
const decoded = decodePayment(encoded);
|
|
176
|
+
if (isPaymentPayload(decoded) && "x402Version" in decoded) {
|
|
177
|
+
return decoded.x402Version;
|
|
178
|
+
}
|
|
179
|
+
return 1;
|
|
180
|
+
} catch {
|
|
181
|
+
return 1;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return 1;
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
function extractPaymentFromHeaders(headers) {
|
|
189
|
+
const encoded = headers.get(X402_HEADERS.PAYMENT);
|
|
190
|
+
if (!encoded) return null;
|
|
191
|
+
try {
|
|
192
|
+
return decodePayment(encoded);
|
|
193
|
+
} catch {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function createPaymentRequiredHeaders(requirements) {
|
|
198
|
+
const accepts = Array.isArray(requirements) ? requirements : [requirements];
|
|
199
|
+
const response = {
|
|
200
|
+
x402Version: 1,
|
|
201
|
+
accepts
|
|
202
|
+
};
|
|
203
|
+
return {
|
|
204
|
+
[X402_HEADERS.PAYMENT_REQUIRED]: safeBase64Encode(JSON.stringify(response))
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function createSettlementHeaders(settlement) {
|
|
208
|
+
return {
|
|
209
|
+
[X402_HEADERS.PAYMENT_RESPONSE]: encodeSettlementResponse(settlement)
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function isLegacyV1(payload) {
|
|
213
|
+
return typeof payload === "object" && payload !== null && "v" in payload && typeof payload.v === "number";
|
|
214
|
+
}
|
|
215
|
+
function isLegacyV2(payload) {
|
|
216
|
+
return typeof payload === "object" && payload !== null && "signature" in payload && typeof payload.signature === "object";
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/utils/x402.ts
|
|
220
|
+
import { randomBytes } from "crypto";
|
|
221
|
+
function createNonce() {
|
|
222
|
+
const bytes = randomBytes(32);
|
|
223
|
+
return `0x${bytes.toString("hex")}`;
|
|
224
|
+
}
|
|
225
|
+
function toAtomicUnits(amount, decimals = 6) {
|
|
226
|
+
const parts = amount.split(".");
|
|
227
|
+
const whole = parts[0];
|
|
228
|
+
const fractional = parts[1] || "";
|
|
229
|
+
const paddedFractional = fractional.padEnd(decimals, "0").slice(0, decimals);
|
|
230
|
+
return `${whole}${paddedFractional}`;
|
|
231
|
+
}
|
|
232
|
+
function fromAtomicUnits(amount, decimals = 6) {
|
|
233
|
+
const value = BigInt(amount);
|
|
234
|
+
const divisor = BigInt(10 ** decimals);
|
|
235
|
+
const whole = (value / divisor).toString();
|
|
236
|
+
const fractional = (value % divisor).toString().padStart(decimals, "0").replace(/0+$/, "");
|
|
237
|
+
if (fractional.length === 0) {
|
|
238
|
+
return whole;
|
|
239
|
+
}
|
|
240
|
+
return `${whole}.${fractional}`;
|
|
241
|
+
}
|
|
242
|
+
function parseSignature(signature) {
|
|
243
|
+
const hex = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
244
|
+
const r = `0x${hex.slice(0, 64)}`;
|
|
245
|
+
const s = `0x${hex.slice(64, 128)}`;
|
|
246
|
+
const v = parseInt(hex.slice(128, 130) || "1c", 16);
|
|
247
|
+
return { r, s, v };
|
|
248
|
+
}
|
|
249
|
+
function combineSignature(r, s, v) {
|
|
250
|
+
const rHex = r.startsWith("0x") ? r.slice(2) : r;
|
|
251
|
+
const sHex = s.startsWith("0x") ? s.slice(2) : s;
|
|
252
|
+
const vHex = v.toString(16).padStart(2, "0");
|
|
253
|
+
return `0x${rHex}${sHex}${vHex}`;
|
|
254
|
+
}
|
|
255
|
+
function caip2ToNetwork(caip2Id) {
|
|
256
|
+
const match = caip2Id.match(/^eip155:(\d+)$/);
|
|
257
|
+
if (!match) {
|
|
258
|
+
return caip2Id;
|
|
259
|
+
}
|
|
260
|
+
const chainId = parseInt(match[1], 10);
|
|
261
|
+
const chainIdToNetwork = {
|
|
262
|
+
1: "ethereum",
|
|
263
|
+
8453: "base",
|
|
264
|
+
84532: "base-sepolia",
|
|
265
|
+
137: "polygon",
|
|
266
|
+
42161: "arbitrum",
|
|
267
|
+
421614: "arbitrum-sepolia",
|
|
268
|
+
10: "optimism",
|
|
269
|
+
11155420: "optimism-sepolia",
|
|
270
|
+
11155111: "ethereum-sepolia"
|
|
271
|
+
};
|
|
272
|
+
return chainIdToNetwork[chainId] || caip2Id;
|
|
273
|
+
}
|
|
274
|
+
function networkToCaip2(network) {
|
|
275
|
+
const networkToChainId = {
|
|
276
|
+
ethereum: 1,
|
|
277
|
+
base: 8453,
|
|
278
|
+
"base-sepolia": 84532,
|
|
279
|
+
polygon: 137,
|
|
280
|
+
arbitrum: 42161,
|
|
281
|
+
"arbitrum-sepolia": 421614,
|
|
282
|
+
optimism: 10,
|
|
283
|
+
"optimism-sepolia": 11155420,
|
|
284
|
+
"ethereum-sepolia": 11155111
|
|
285
|
+
};
|
|
286
|
+
const chainId = networkToChainId[network];
|
|
287
|
+
if (chainId) {
|
|
288
|
+
return `eip155:${chainId}`;
|
|
289
|
+
}
|
|
290
|
+
if (network.startsWith("eip155:")) {
|
|
291
|
+
return network;
|
|
292
|
+
}
|
|
293
|
+
return `eip155:0`;
|
|
294
|
+
}
|
|
295
|
+
function getCurrentTimestamp() {
|
|
296
|
+
return Math.floor(Date.now() / 1e3);
|
|
297
|
+
}
|
|
298
|
+
function isValidAddress(address) {
|
|
299
|
+
return /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
300
|
+
}
|
|
301
|
+
function normalizeAddress(address) {
|
|
302
|
+
return address.toLowerCase();
|
|
303
|
+
}
|
|
304
|
+
|
|
1
305
|
// src/types/v1.ts
|
|
2
306
|
var V1_HEADERS = {
|
|
3
307
|
PAYMENT: "X-PAYMENT",
|
|
@@ -9,10 +313,10 @@ function encodePaymentPayload(payload) {
|
|
|
9
313
|
function decodePaymentPayload(encoded) {
|
|
10
314
|
return JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
|
|
11
315
|
}
|
|
12
|
-
function
|
|
316
|
+
function encodeSettlementResponse2(response) {
|
|
13
317
|
return Buffer.from(JSON.stringify(response)).toString("base64");
|
|
14
318
|
}
|
|
15
|
-
function
|
|
319
|
+
function decodeSettlementResponse2(encoded) {
|
|
16
320
|
return JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
|
|
17
321
|
}
|
|
18
322
|
|
|
@@ -167,46 +471,6 @@ var ERC20_ABI = [
|
|
|
167
471
|
}
|
|
168
472
|
];
|
|
169
473
|
|
|
170
|
-
// src/encoding.ts
|
|
171
|
-
var base64Encode = (data) => Buffer.from(JSON.stringify(data)).toString("base64");
|
|
172
|
-
var base64Decode = (encoded) => JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
|
|
173
|
-
var jsonEncode = (data) => JSON.stringify(data);
|
|
174
|
-
var jsonDecode = (encoded) => JSON.parse(encoded);
|
|
175
|
-
var encodePaymentV1 = (payload) => base64Encode(payload);
|
|
176
|
-
var decodePaymentV1 = (encoded) => base64Decode(encoded);
|
|
177
|
-
var encodeSettlementV1 = (response) => base64Encode(response);
|
|
178
|
-
var decodeSettlementV1 = (encoded) => base64Decode(encoded);
|
|
179
|
-
var encodePaymentV2 = (payload) => jsonEncode(payload);
|
|
180
|
-
var decodePaymentV2 = (encoded) => jsonDecode(encoded);
|
|
181
|
-
var encodeSettlementV2 = (response) => jsonEncode(response);
|
|
182
|
-
var decodeSettlementV2 = (encoded) => jsonDecode(encoded);
|
|
183
|
-
var detectPaymentVersion = (headers) => {
|
|
184
|
-
if (headers.has(V1_HEADERS.PAYMENT)) return 1;
|
|
185
|
-
if (headers.has(V2_HEADERS.PAYMENT_SIGNATURE)) return 2;
|
|
186
|
-
return null;
|
|
187
|
-
};
|
|
188
|
-
var decodePayment = (headers) => {
|
|
189
|
-
const version = detectPaymentVersion(headers);
|
|
190
|
-
if (version === null) {
|
|
191
|
-
throw new Error("No valid payment headers found. Expected X-PAYMENT (v1) or PAYMENT-SIGNATURE (v2)");
|
|
192
|
-
}
|
|
193
|
-
const headerName = version === 1 ? V1_HEADERS.PAYMENT : V2_HEADERS.PAYMENT_SIGNATURE;
|
|
194
|
-
const encoded = headers.get(headerName);
|
|
195
|
-
if (!encoded) throw new Error(`Header ${headerName} is empty`);
|
|
196
|
-
return version === 1 ? decodePaymentV1(encoded) : decodePaymentV2(encoded);
|
|
197
|
-
};
|
|
198
|
-
var decodeSettlement = (headers) => {
|
|
199
|
-
const v1Response = headers.get(V1_HEADERS.PAYMENT_RESPONSE);
|
|
200
|
-
if (v1Response) return decodeSettlementV1(v1Response);
|
|
201
|
-
const v2Response = headers.get(V2_HEADERS.PAYMENT_RESPONSE);
|
|
202
|
-
if (v2Response) return decodeSettlementV2(v2Response);
|
|
203
|
-
throw new Error("No valid settlement response headers found. Expected X-PAYMENT-RESPONSE (v1) or PAYMENT-RESPONSE (v2)");
|
|
204
|
-
};
|
|
205
|
-
var isPaymentV1 = (payload) => "v" in payload && typeof payload.v === "number";
|
|
206
|
-
var isPaymentV2 = (payload) => "signature" in payload && typeof payload.signature === "object";
|
|
207
|
-
var isSettlementV1 = (response) => "success" in response;
|
|
208
|
-
var isSettlementV2 = (response) => "status" in response;
|
|
209
|
-
|
|
210
474
|
// src/eip712.ts
|
|
211
475
|
var EIP712_TYPES = {
|
|
212
476
|
TransferWithAuthorization: [
|
|
@@ -664,35 +928,93 @@ var isResolvedNetwork = (value) => {
|
|
|
664
928
|
var isResolvedToken = (value) => {
|
|
665
929
|
return typeof value === "object" && value !== null && "config" in value && "caipAsset" in value;
|
|
666
930
|
};
|
|
931
|
+
|
|
932
|
+
// src/encoding.ts
|
|
933
|
+
var base64Encode = (data) => Buffer.from(JSON.stringify(data)).toString("base64");
|
|
934
|
+
var base64Decode = (encoded) => JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
|
|
935
|
+
var jsonEncode = (data) => JSON.stringify(data);
|
|
936
|
+
var jsonDecode = (encoded) => JSON.parse(encoded);
|
|
937
|
+
var encodePaymentV1 = (payload) => base64Encode(payload);
|
|
938
|
+
var decodePaymentV1 = (encoded) => base64Decode(encoded);
|
|
939
|
+
var encodeSettlementV1 = (response) => base64Encode(response);
|
|
940
|
+
var decodeSettlementV1 = (encoded) => base64Decode(encoded);
|
|
941
|
+
var encodePaymentV2 = (payload) => jsonEncode(payload);
|
|
942
|
+
var decodePaymentV2 = (encoded) => jsonDecode(encoded);
|
|
943
|
+
var encodeSettlementV2 = (response) => jsonEncode(response);
|
|
944
|
+
var decodeSettlementV2 = (encoded) => jsonDecode(encoded);
|
|
945
|
+
var detectPaymentVersion2 = (headers) => {
|
|
946
|
+
if (headers.has(V1_HEADERS.PAYMENT)) return 1;
|
|
947
|
+
if (headers.has(V2_HEADERS.PAYMENT_SIGNATURE)) return 2;
|
|
948
|
+
return null;
|
|
949
|
+
};
|
|
950
|
+
var decodePayment2 = (headers) => {
|
|
951
|
+
const version = detectPaymentVersion2(headers);
|
|
952
|
+
if (version === null) {
|
|
953
|
+
throw new Error("No valid payment headers found. Expected X-PAYMENT (v1) or PAYMENT-SIGNATURE (v2)");
|
|
954
|
+
}
|
|
955
|
+
const headerName = version === 1 ? V1_HEADERS.PAYMENT : V2_HEADERS.PAYMENT_SIGNATURE;
|
|
956
|
+
const encoded = headers.get(headerName);
|
|
957
|
+
if (!encoded) throw new Error(`Header ${headerName} is empty`);
|
|
958
|
+
return version === 1 ? decodePaymentV1(encoded) : decodePaymentV2(encoded);
|
|
959
|
+
};
|
|
960
|
+
var decodeSettlement = (headers) => {
|
|
961
|
+
const v1Response = headers.get(V1_HEADERS.PAYMENT_RESPONSE);
|
|
962
|
+
if (v1Response) return decodeSettlementV1(v1Response);
|
|
963
|
+
const v2Response = headers.get(V2_HEADERS.PAYMENT_RESPONSE);
|
|
964
|
+
if (v2Response) return decodeSettlementV2(v2Response);
|
|
965
|
+
throw new Error("No valid settlement response headers found. Expected X-PAYMENT-RESPONSE (v1) or PAYMENT-RESPONSE (v2)");
|
|
966
|
+
};
|
|
967
|
+
var isPaymentV1 = (payload) => "v" in payload && typeof payload.v === "number";
|
|
968
|
+
var isPaymentV2 = (payload) => "signature" in payload && typeof payload.signature === "object";
|
|
969
|
+
var isSettlementV1 = (response) => "success" in response;
|
|
970
|
+
var isSettlementV2 = (response) => "status" in response;
|
|
667
971
|
export {
|
|
668
972
|
EIP712_TYPES,
|
|
669
973
|
ERC20_ABI,
|
|
670
974
|
NETWORKS,
|
|
975
|
+
SCHEMES,
|
|
671
976
|
USDC_DOMAIN,
|
|
672
977
|
V1_HEADERS,
|
|
673
978
|
V2_HEADERS,
|
|
979
|
+
X402_HEADERS,
|
|
980
|
+
X402_VERSION,
|
|
981
|
+
caip2ToNetwork,
|
|
674
982
|
checkFacilitatorSupport,
|
|
983
|
+
combineSignature,
|
|
675
984
|
createEIP712Domain,
|
|
676
985
|
createError,
|
|
986
|
+
createNonce,
|
|
987
|
+
createPaymentRequiredHeaders,
|
|
988
|
+
createSettlementHeaders,
|
|
677
989
|
createTransferWithAuthorization,
|
|
678
990
|
decodePayment,
|
|
991
|
+
decodePayment2 as decodePaymentLegacy,
|
|
679
992
|
decodePaymentPayload,
|
|
680
993
|
decodePaymentV1,
|
|
681
994
|
decodePaymentV2,
|
|
682
|
-
decodeSettlement,
|
|
995
|
+
decodeSettlement as decodeSettlementLegacy,
|
|
683
996
|
decodeSettlementResponse,
|
|
997
|
+
decodeSettlementResponse2 as decodeSettlementResponseV1,
|
|
684
998
|
decodeSettlementV1,
|
|
685
999
|
decodeSettlementV2,
|
|
1000
|
+
decodeX402Response,
|
|
686
1001
|
detectPaymentVersion,
|
|
1002
|
+
detectPaymentVersion2 as detectPaymentVersionLegacy,
|
|
1003
|
+
encodePayment,
|
|
687
1004
|
encodePaymentPayload,
|
|
688
1005
|
encodePaymentV1,
|
|
689
1006
|
encodePaymentV2,
|
|
690
1007
|
encodeSettlementResponse,
|
|
1008
|
+
encodeSettlementResponse2 as encodeSettlementResponseV1,
|
|
691
1009
|
encodeSettlementV1,
|
|
692
1010
|
encodeSettlementV2,
|
|
1011
|
+
encodeX402Response,
|
|
1012
|
+
extractPaymentFromHeaders,
|
|
1013
|
+
fromAtomicUnits,
|
|
693
1014
|
getAllCustomTokens,
|
|
694
1015
|
getAvailableNetworks,
|
|
695
1016
|
getAvailableTokens,
|
|
1017
|
+
getCurrentTimestamp,
|
|
696
1018
|
getCustomToken,
|
|
697
1019
|
getMainnets,
|
|
698
1020
|
getNetworkByChainId,
|
|
@@ -700,7 +1022,7 @@ export {
|
|
|
700
1022
|
getPaymentHeaderName,
|
|
701
1023
|
getPaymentRequiredHeaderName,
|
|
702
1024
|
getPaymentResponseHeaderName,
|
|
703
|
-
getPaymentVersion
|
|
1025
|
+
getPaymentVersion,
|
|
704
1026
|
getRequirementsVersion,
|
|
705
1027
|
getSettlementVersion,
|
|
706
1028
|
getTestnets,
|
|
@@ -709,6 +1031,10 @@ export {
|
|
|
709
1031
|
isCAIP2ChainId,
|
|
710
1032
|
isCAIPAssetId,
|
|
711
1033
|
isCustomToken,
|
|
1034
|
+
isExactEvmPayload,
|
|
1035
|
+
isLegacyV1,
|
|
1036
|
+
isLegacyV2,
|
|
1037
|
+
isPaymentPayload,
|
|
712
1038
|
isPaymentV1,
|
|
713
1039
|
isPaymentV2,
|
|
714
1040
|
isResolvedNetwork,
|
|
@@ -718,11 +1044,19 @@ export {
|
|
|
718
1044
|
isSettlementV2,
|
|
719
1045
|
isV1,
|
|
720
1046
|
isV2,
|
|
1047
|
+
isValidAddress,
|
|
721
1048
|
isValidationError,
|
|
1049
|
+
legacyToPaymentPayload,
|
|
1050
|
+
networkToCaip2,
|
|
1051
|
+
normalizeAddress,
|
|
1052
|
+
parseSignature,
|
|
722
1053
|
registerToken,
|
|
723
1054
|
resolveFacilitator,
|
|
724
1055
|
resolveNetwork,
|
|
725
1056
|
resolveToken,
|
|
1057
|
+
safeBase64Decode,
|
|
1058
|
+
safeBase64Encode,
|
|
1059
|
+
toAtomicUnits,
|
|
726
1060
|
unregisterToken,
|
|
727
1061
|
validateAcceptConfig,
|
|
728
1062
|
validatePaymentConfig,
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X402 Protocol Types - Coinbase Compatible Format
|
|
3
|
+
*
|
|
4
|
+
* This module provides types that match the official Coinbase x402 SDK format
|
|
5
|
+
* for full interoperability with their facilitator and extensions.
|
|
6
|
+
*/
|
|
7
|
+
export type Address = `0x${string}`;
|
|
8
|
+
export type Hex = `0x${string}`;
|
|
9
|
+
export declare const X402_VERSION: 1;
|
|
10
|
+
export type X402Version = typeof X402_VERSION;
|
|
11
|
+
export declare const SCHEMES: readonly ["exact"];
|
|
12
|
+
export type Scheme = (typeof SCHEMES)[number];
|
|
13
|
+
export type Network = "base" | "base-sepolia" | "ethereum" | "ethereum-sepolia" | "polygon" | "polygon-amoy" | "arbitrum" | "arbitrum-sepolia" | "optimism" | "optimism-sepolia" | string;
|
|
14
|
+
/**
|
|
15
|
+
* EIP-3009 TransferWithAuthorization authorization data
|
|
16
|
+
*/
|
|
17
|
+
export interface ExactEvmAuthorization {
|
|
18
|
+
from: Address;
|
|
19
|
+
to: Address;
|
|
20
|
+
value: string;
|
|
21
|
+
validAfter: string;
|
|
22
|
+
validBefore: string;
|
|
23
|
+
nonce: Hex;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Exact EVM payment payload structure
|
|
27
|
+
*/
|
|
28
|
+
export interface ExactEvmPayload {
|
|
29
|
+
signature: Hex;
|
|
30
|
+
authorization: ExactEvmAuthorization;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Payment payload - Coinbase compatible format
|
|
34
|
+
* This is the unified format that works with both v1 and v2
|
|
35
|
+
*/
|
|
36
|
+
export interface PaymentPayload {
|
|
37
|
+
x402Version: X402Version;
|
|
38
|
+
scheme: Scheme;
|
|
39
|
+
network: Network;
|
|
40
|
+
payload: ExactEvmPayload;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Unsigned payment payload (before signing)
|
|
44
|
+
*/
|
|
45
|
+
export interface UnsignedPaymentPayload {
|
|
46
|
+
x402Version: X402Version;
|
|
47
|
+
scheme: Scheme;
|
|
48
|
+
network: Network;
|
|
49
|
+
payload: Omit<ExactEvmPayload, "signature"> & {
|
|
50
|
+
signature: undefined;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Payment requirements for 402 response
|
|
55
|
+
*/
|
|
56
|
+
export interface PaymentRequirements {
|
|
57
|
+
scheme: Scheme;
|
|
58
|
+
network: Network;
|
|
59
|
+
maxAmountRequired: string;
|
|
60
|
+
resource: string;
|
|
61
|
+
description: string;
|
|
62
|
+
mimeType: string;
|
|
63
|
+
outputSchema?: Record<string, unknown>;
|
|
64
|
+
payTo: Address;
|
|
65
|
+
maxTimeoutSeconds: number;
|
|
66
|
+
asset: Address;
|
|
67
|
+
extra?: Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Settlement response
|
|
71
|
+
*/
|
|
72
|
+
export interface SettlementResponse {
|
|
73
|
+
success: boolean;
|
|
74
|
+
errorReason?: string;
|
|
75
|
+
payer?: Address;
|
|
76
|
+
transaction: string;
|
|
77
|
+
network: Network;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Verify response
|
|
81
|
+
*/
|
|
82
|
+
export interface VerifyResponse {
|
|
83
|
+
isValid: boolean;
|
|
84
|
+
invalidReason?: string;
|
|
85
|
+
payer?: Address;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* X402 response structure for 402 errors
|
|
89
|
+
*/
|
|
90
|
+
export interface X402Response {
|
|
91
|
+
x402Version: X402Version;
|
|
92
|
+
error?: string;
|
|
93
|
+
accepts?: PaymentRequirements[];
|
|
94
|
+
payer?: Address;
|
|
95
|
+
}
|
|
96
|
+
export interface PaymentPayloadV1 {
|
|
97
|
+
from: string;
|
|
98
|
+
to: string;
|
|
99
|
+
amount: string;
|
|
100
|
+
nonce: string;
|
|
101
|
+
expiry: number;
|
|
102
|
+
v: number;
|
|
103
|
+
r: string;
|
|
104
|
+
s: string;
|
|
105
|
+
chainId: number;
|
|
106
|
+
contractAddress: string;
|
|
107
|
+
network: string;
|
|
108
|
+
}
|
|
109
|
+
export interface PaymentPayloadV2 {
|
|
110
|
+
from: Address;
|
|
111
|
+
to: Address | {
|
|
112
|
+
role?: string;
|
|
113
|
+
callback?: string;
|
|
114
|
+
};
|
|
115
|
+
amount: string;
|
|
116
|
+
nonce: string;
|
|
117
|
+
expiry: number;
|
|
118
|
+
signature: {
|
|
119
|
+
v: number;
|
|
120
|
+
r: string;
|
|
121
|
+
s: string;
|
|
122
|
+
};
|
|
123
|
+
chainId: `eip155:${string}`;
|
|
124
|
+
assetId: `eip155:${string}/erc20:${string}`;
|
|
125
|
+
extensions?: Record<string, unknown>;
|
|
126
|
+
}
|
|
127
|
+
export type LegacyPaymentPayload = PaymentPayloadV1 | PaymentPayloadV2;
|
|
128
|
+
/**
|
|
129
|
+
* Type guards
|
|
130
|
+
*/
|
|
131
|
+
export declare function isPaymentPayload(obj: unknown): obj is PaymentPayload;
|
|
132
|
+
export declare function isExactEvmPayload(obj: unknown): obj is ExactEvmPayload;
|
|
133
|
+
/**
|
|
134
|
+
* Convert legacy payload to new format
|
|
135
|
+
*/
|
|
136
|
+
export declare function legacyToPaymentPayload(legacy: LegacyPaymentPayload | PaymentPayload): PaymentPayload;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X402 Protocol Utilities - Coinbase Compatible
|
|
3
|
+
*
|
|
4
|
+
* Helper functions for nonce generation, amount conversion, and other utilities.
|
|
5
|
+
*/
|
|
6
|
+
import type { Hex, Address } from "../types/x402";
|
|
7
|
+
/**
|
|
8
|
+
* Generate a random 32-byte nonce as hex string
|
|
9
|
+
* Matches Coinbase SDK format: "0x" + 64 hex characters
|
|
10
|
+
*/
|
|
11
|
+
export declare function createNonce(): Hex;
|
|
12
|
+
/**
|
|
13
|
+
* Convert human-readable amount to atomic units
|
|
14
|
+
* e.g., "1.5" USDC -> "1500000" (6 decimals)
|
|
15
|
+
*/
|
|
16
|
+
export declare function toAtomicUnits(amount: string, decimals?: number): string;
|
|
17
|
+
/**
|
|
18
|
+
* Convert atomic units to human-readable amount
|
|
19
|
+
* e.g., "1500000" -> "1.5" USDC (6 decimals)
|
|
20
|
+
*/
|
|
21
|
+
export declare function fromAtomicUnits(amount: string, decimals?: number): string;
|
|
22
|
+
/**
|
|
23
|
+
* Parse signature from hex string to components
|
|
24
|
+
* Returns { r, s, v } where v is 27 or 28
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseSignature(signature: Hex): {
|
|
27
|
+
r: Hex;
|
|
28
|
+
s: Hex;
|
|
29
|
+
v: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Combine signature components into hex string
|
|
33
|
+
*/
|
|
34
|
+
export declare function combineSignature(r: Hex, s: Hex, v: number): Hex;
|
|
35
|
+
/**
|
|
36
|
+
* Convert CAIP-2 chain ID to network name
|
|
37
|
+
* e.g., "eip155:8453" -> "base"
|
|
38
|
+
*/
|
|
39
|
+
export declare function caip2ToNetwork(caip2Id: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Convert network name to CAIP-2 chain ID
|
|
42
|
+
* e.g., "base" -> "eip155:8453"
|
|
43
|
+
*/
|
|
44
|
+
export declare function networkToCaip2(network: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Get current Unix timestamp in seconds
|
|
47
|
+
*/
|
|
48
|
+
export declare function getCurrentTimestamp(): number;
|
|
49
|
+
/**
|
|
50
|
+
* Validate Ethereum address
|
|
51
|
+
*/
|
|
52
|
+
export declare function isValidAddress(address: string): address is Address;
|
|
53
|
+
/**
|
|
54
|
+
* Normalize address to checksum format (basic lowercase)
|
|
55
|
+
*/
|
|
56
|
+
export declare function normalizeAddress(address: string): Address;
|