@chipi-stack/core 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE-starknet-sdk.md +13 -0
- package/README.md +62 -0
- package/dist/index.d.ts +1534 -16
- package/dist/index.js +10998 -16
- package/dist/index.js.map +1 -1
- package/package.json +8 -5
- package/dist/estimation/estimate-fee.d.ts +0 -21
- package/dist/estimation/estimate-fee.d.ts.map +0 -1
- package/dist/estimation/estimate-fee.js +0 -34
- package/dist/estimation/estimate-fee.js.map +0 -1
- package/dist/estimation/types.d.ts +0 -14
- package/dist/estimation/types.d.ts.map +0 -1
- package/dist/estimation/types.js +0 -2
- package/dist/estimation/types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/signers/create-account.d.ts +0 -21
- package/dist/signers/create-account.d.ts.map +0 -1
- package/dist/signers/create-account.js +0 -19
- package/dist/signers/create-account.js.map +0 -1
- package/dist/signers/direct-signer.d.ts +0 -18
- package/dist/signers/direct-signer.d.ts.map +0 -1
- package/dist/signers/direct-signer.js +0 -32
- package/dist/signers/direct-signer.js.map +0 -1
- package/dist/signers/external-signer.d.ts +0 -17
- package/dist/signers/external-signer.d.ts.map +0 -1
- package/dist/signers/external-signer.js +0 -19
- package/dist/signers/external-signer.js.map +0 -1
- package/dist/signers/passkey-signer.d.ts +0 -25
- package/dist/signers/passkey-signer.d.ts.map +0 -1
- package/dist/signers/passkey-signer.js +0 -24
- package/dist/signers/passkey-signer.js.map +0 -1
- package/dist/signers/starknet-signer-adapter.d.ts +0 -18
- package/dist/signers/starknet-signer-adapter.d.ts.map +0 -1
- package/dist/signers/starknet-signer-adapter.js +0 -26
- package/dist/signers/starknet-signer-adapter.js.map +0 -1
- package/dist/signers/types.d.ts +0 -19
- package/dist/signers/types.d.ts.map +0 -1
- package/dist/signers/types.js +0 -2
- package/dist/signers/types.js.map +0 -1
- package/dist/tokens/amount.d.ts +0 -72
- package/dist/tokens/amount.d.ts.map +0 -1
- package/dist/tokens/amount.js +0 -166
- package/dist/tokens/amount.js.map +0 -1
- package/dist/tokens/erc20.d.ts +0 -38
- package/dist/tokens/erc20.d.ts.map +0 -1
- package/dist/tokens/erc20.js +0 -79
- package/dist/tokens/erc20.js.map +0 -1
- package/dist/tokens/presets/mainnet.json +0 -38
- package/dist/tokens/presets/sepolia.json +0 -20
- package/dist/tokens/registry.d.ts +0 -27
- package/dist/tokens/registry.d.ts.map +0 -1
- package/dist/tokens/registry.js +0 -38
- package/dist/tokens/registry.js.map +0 -1
- package/dist/transactions/tx-builder.d.ts +0 -74
- package/dist/transactions/tx-builder.d.ts.map +0 -1
- package/dist/transactions/tx-builder.js +0 -117
- package/dist/transactions/tx-builder.js.map +0 -1
- package/dist/transactions/types.d.ts +0 -11
- package/dist/transactions/types.d.ts.map +0 -1
- package/dist/transactions/types.js +0 -2
- package/dist/transactions/types.js.map +0 -1
- package/dist/x402/client.d.ts +0 -112
- package/dist/x402/client.d.ts.map +0 -1
- package/dist/x402/client.js +0 -270
- package/dist/x402/client.js.map +0 -1
- package/dist/x402/index.d.ts +0 -2
- package/dist/x402/index.d.ts.map +0 -1
- package/dist/x402/index.js +0 -2
- package/dist/x402/index.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transactions/types.ts"],"names":[],"mappings":""}
|
package/dist/x402/client.d.ts
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import type { Account, TypedData } from "starknet";
|
|
2
|
-
import type { PaymentRequirement, PaymentPayload, X402ClientConfig } from "@chipi-stack/types";
|
|
3
|
-
/** SNIP-12 domain for x402 payments */
|
|
4
|
-
export declare const X402_DOMAIN: {
|
|
5
|
-
name: string;
|
|
6
|
-
version: string;
|
|
7
|
-
chainId: string;
|
|
8
|
-
};
|
|
9
|
-
/** SNIP-12 typed data structure for x402 payment */
|
|
10
|
-
export declare const X402_TYPES: {
|
|
11
|
-
StarknetDomain: {
|
|
12
|
-
name: string;
|
|
13
|
-
type: string;
|
|
14
|
-
}[];
|
|
15
|
-
Payment: {
|
|
16
|
-
name: string;
|
|
17
|
-
type: string;
|
|
18
|
-
}[];
|
|
19
|
-
};
|
|
20
|
-
/** Simple convenience params for buildX402TypedData */
|
|
21
|
-
export interface BuildX402SimpleParams {
|
|
22
|
-
/** Sender address */
|
|
23
|
-
from: string;
|
|
24
|
-
/** Recipient address */
|
|
25
|
-
recipient: string;
|
|
26
|
-
/** Amount in USDC base units (string) */
|
|
27
|
-
amount: string;
|
|
28
|
-
/** Nonce for replay protection */
|
|
29
|
-
nonce: string;
|
|
30
|
-
/** Seconds until expiry (default: 300) */
|
|
31
|
-
expiry?: number;
|
|
32
|
-
/** Asset address (default: USDC mainnet) */
|
|
33
|
-
asset?: string;
|
|
34
|
-
}
|
|
35
|
-
/** Full message params (original API) */
|
|
36
|
-
interface BuildX402FullMessage {
|
|
37
|
-
from_address: string;
|
|
38
|
-
to_address: string;
|
|
39
|
-
amount: string;
|
|
40
|
-
asset: string;
|
|
41
|
-
valid_until: string;
|
|
42
|
-
nonce: string;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Build the full SNIP-12 typed data object for an x402 payment.
|
|
46
|
-
* Centralises the structure so client, facilitator, and React hook stay in sync.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* // Full params (original)
|
|
51
|
-
* buildX402TypedData({ from_address, to_address, amount, asset, valid_until, nonce })
|
|
52
|
-
*
|
|
53
|
-
* // Simple convenience params
|
|
54
|
-
* buildX402TypedData({ from: sender, recipient, amount, nonce, expiry: 300 })
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
export declare function buildX402TypedData(message: BuildX402FullMessage | BuildX402SimpleParams): TypedData;
|
|
58
|
-
/**
|
|
59
|
-
* Minimal fetch-compatible interfaces.
|
|
60
|
-
* These mirror the standard Fetch API but allow the client to work
|
|
61
|
-
* in both browser and Node.js (18+) environments without requiring DOM lib.
|
|
62
|
-
*/
|
|
63
|
-
interface FetchResponse {
|
|
64
|
-
status: number;
|
|
65
|
-
headers: {
|
|
66
|
-
get(name: string): string | null;
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* x402 payment client for Starknet.
|
|
71
|
-
*
|
|
72
|
-
* Wraps fetch calls with automatic HTTP 402 payment handling.
|
|
73
|
-
* When a server returns 402 Payment Required, the client:
|
|
74
|
-
* 1. Parses the payment requirement from the response header
|
|
75
|
-
* 2. Validates against configured limits (max amount, allowed recipients)
|
|
76
|
-
* 3. Signs a SNIP-12 typed data payment message
|
|
77
|
-
* 4. Retries the request with the signed payment in the X-PAYMENT header
|
|
78
|
-
*
|
|
79
|
-
* Works with any Starknet Account (DirectSigner, passkey, session key, external wallet).
|
|
80
|
-
* When used with a session key account, payments are fully automatic (no user interaction).
|
|
81
|
-
*/
|
|
82
|
-
export declare class X402Client {
|
|
83
|
-
private readonly account;
|
|
84
|
-
private readonly config;
|
|
85
|
-
private readonly fetchFn;
|
|
86
|
-
constructor(account: Account, config?: X402ClientConfig);
|
|
87
|
-
/**
|
|
88
|
-
* Wrap a fetch call with x402 payment handling.
|
|
89
|
-
* If the server returns 402, automatically sign payment and retry.
|
|
90
|
-
*/
|
|
91
|
-
fetch(url: string, init?: Record<string, any>): Promise<FetchResponse>;
|
|
92
|
-
/**
|
|
93
|
-
* Parse PAYMENT-REQUIRED header from 402 response.
|
|
94
|
-
*/
|
|
95
|
-
parsePaymentRequired(response: FetchResponse): PaymentRequirement;
|
|
96
|
-
/**
|
|
97
|
-
* Validate payment requirement against client configuration limits.
|
|
98
|
-
* Throws if the payment would exceed maxPaymentAmount or recipient is not whitelisted.
|
|
99
|
-
*/
|
|
100
|
-
validateRequirement(requirement: PaymentRequirement): void;
|
|
101
|
-
/**
|
|
102
|
-
* Sign a SNIP-12 typed data payment message for the given requirement.
|
|
103
|
-
* Returns a PaymentPayload ready to be sent as the X-PAYMENT header.
|
|
104
|
-
*/
|
|
105
|
-
signPayment(requirement: PaymentRequirement): Promise<PaymentPayload>;
|
|
106
|
-
/**
|
|
107
|
-
* Retry the original request with the X-PAYMENT header containing the signed payment.
|
|
108
|
-
*/
|
|
109
|
-
private retryWithPayment;
|
|
110
|
-
}
|
|
111
|
-
export {};
|
|
112
|
-
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/x402/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAc/F,uCAAuC;AACvC,eAAO,MAAM,WAAW;;;;CAIvB,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,UAAU;;;;;;;;;CActB,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,qBAAqB;IACpC,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,yCAAyC;AACzC,UAAU,oBAAoB;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAQD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,oBAAoB,GAAG,qBAAqB,GACpD,SAAS,CA0BX;AAED;;;;GAIG;AACH,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAC/C;AAQD;;;;;;;;;;;;GAYG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoE;IAC3F,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEtB,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,gBAAgB;IAUvD;;;OAGG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IAa5E;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,aAAa,GAAG,kBAAkB;IA+DjE;;;OAGG;IACH,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,GAAG,IAAI;IAsC1D;;;OAGG;IACG,WAAW,CAAC,WAAW,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;IAkC3E;;OAEG;YACW,gBAAgB;CAgB/B"}
|
package/dist/x402/client.js
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
/** USDC native address on Starknet mainnet */
|
|
2
|
-
const USDC_MAINNET = "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
|
|
3
|
-
/** USDC decimals */
|
|
4
|
-
const USDC_DECIMALS = 6;
|
|
5
|
-
/** Header name for x402 payment requirement */
|
|
6
|
-
const PAYMENT_REQUIRED_HEADER = "payment-required";
|
|
7
|
-
/** Default header name for sending payment */
|
|
8
|
-
const DEFAULT_PAYMENT_HEADER = "X-PAYMENT";
|
|
9
|
-
/** SNIP-12 domain for x402 payments */
|
|
10
|
-
export const X402_DOMAIN = {
|
|
11
|
-
name: "x402-starknet",
|
|
12
|
-
version: "1",
|
|
13
|
-
chainId: "SN_MAIN",
|
|
14
|
-
};
|
|
15
|
-
/** SNIP-12 typed data structure for x402 payment */
|
|
16
|
-
export const X402_TYPES = {
|
|
17
|
-
StarknetDomain: [
|
|
18
|
-
{ name: "name", type: "shortstring" },
|
|
19
|
-
{ name: "version", type: "shortstring" },
|
|
20
|
-
{ name: "chainId", type: "shortstring" },
|
|
21
|
-
],
|
|
22
|
-
Payment: [
|
|
23
|
-
{ name: "from_address", type: "ContractAddress" },
|
|
24
|
-
{ name: "to_address", type: "ContractAddress" },
|
|
25
|
-
{ name: "amount", type: "u256" },
|
|
26
|
-
{ name: "asset", type: "ContractAddress" },
|
|
27
|
-
{ name: "valid_until", type: "u128" },
|
|
28
|
-
{ name: "nonce", type: "felt" },
|
|
29
|
-
],
|
|
30
|
-
};
|
|
31
|
-
function isSimpleParams(params) {
|
|
32
|
-
return "recipient" in params && "from" in params;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Build the full SNIP-12 typed data object for an x402 payment.
|
|
36
|
-
* Centralises the structure so client, facilitator, and React hook stay in sync.
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```typescript
|
|
40
|
-
* // Full params (original)
|
|
41
|
-
* buildX402TypedData({ from_address, to_address, amount, asset, valid_until, nonce })
|
|
42
|
-
*
|
|
43
|
-
* // Simple convenience params
|
|
44
|
-
* buildX402TypedData({ from: sender, recipient, amount, nonce, expiry: 300 })
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
export function buildX402TypedData(message) {
|
|
48
|
-
let resolved;
|
|
49
|
-
if (isSimpleParams(message)) {
|
|
50
|
-
const validUntil = Math.floor(Date.now() / 1000) + (message.expiry ?? 300);
|
|
51
|
-
resolved = {
|
|
52
|
-
from_address: message.from,
|
|
53
|
-
to_address: message.recipient,
|
|
54
|
-
amount: message.amount,
|
|
55
|
-
asset: message.asset ?? USDC_MAINNET,
|
|
56
|
-
valid_until: String(validUntil),
|
|
57
|
-
nonce: message.nonce,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
resolved = message;
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
types: X402_TYPES,
|
|
65
|
-
primaryType: "Payment",
|
|
66
|
-
domain: X402_DOMAIN,
|
|
67
|
-
message: {
|
|
68
|
-
...resolved,
|
|
69
|
-
amount: { low: resolved.amount, high: "0" },
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* x402 payment client for Starknet.
|
|
75
|
-
*
|
|
76
|
-
* Wraps fetch calls with automatic HTTP 402 payment handling.
|
|
77
|
-
* When a server returns 402 Payment Required, the client:
|
|
78
|
-
* 1. Parses the payment requirement from the response header
|
|
79
|
-
* 2. Validates against configured limits (max amount, allowed recipients)
|
|
80
|
-
* 3. Signs a SNIP-12 typed data payment message
|
|
81
|
-
* 4. Retries the request with the signed payment in the X-PAYMENT header
|
|
82
|
-
*
|
|
83
|
-
* Works with any Starknet Account (DirectSigner, passkey, session key, external wallet).
|
|
84
|
-
* When used with a session key account, payments are fully automatic (no user interaction).
|
|
85
|
-
*/
|
|
86
|
-
export class X402Client {
|
|
87
|
-
constructor(account, config) {
|
|
88
|
-
this.account = account;
|
|
89
|
-
this.config = {
|
|
90
|
-
headerName: DEFAULT_PAYMENT_HEADER,
|
|
91
|
-
...config,
|
|
92
|
-
};
|
|
93
|
-
// Use global fetch (available in Node 18+ and browsers)
|
|
94
|
-
this.fetchFn = globalThis.fetch;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Wrap a fetch call with x402 payment handling.
|
|
98
|
-
* If the server returns 402, automatically sign payment and retry.
|
|
99
|
-
*/
|
|
100
|
-
async fetch(url, init) {
|
|
101
|
-
const response = await this.fetchFn(url, init);
|
|
102
|
-
if (response.status !== 402) {
|
|
103
|
-
return response;
|
|
104
|
-
}
|
|
105
|
-
const requirement = this.parsePaymentRequired(response);
|
|
106
|
-
this.validateRequirement(requirement);
|
|
107
|
-
const payment = await this.signPayment(requirement);
|
|
108
|
-
return this.retryWithPayment(url, init, payment);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Parse PAYMENT-REQUIRED header from 402 response.
|
|
112
|
-
*/
|
|
113
|
-
parsePaymentRequired(response) {
|
|
114
|
-
const headerValue = response.headers.get(PAYMENT_REQUIRED_HEADER);
|
|
115
|
-
if (!headerValue) {
|
|
116
|
-
throw new Error("Server returned 402 but no PAYMENT-REQUIRED header. " +
|
|
117
|
-
"The server may not support x402 or is misconfigured.");
|
|
118
|
-
}
|
|
119
|
-
let requirement;
|
|
120
|
-
try {
|
|
121
|
-
requirement = JSON.parse(headerValue);
|
|
122
|
-
}
|
|
123
|
-
catch {
|
|
124
|
-
throw new Error(`Malformed PAYMENT-REQUIRED header: invalid JSON. Got: "${headerValue.slice(0, 100)}"`);
|
|
125
|
-
}
|
|
126
|
-
if (!requirement.scheme || !requirement.network || !requirement.maxAmountRequired) {
|
|
127
|
-
throw new Error("Invalid payment requirement: missing required fields (scheme, network, maxAmountRequired)");
|
|
128
|
-
}
|
|
129
|
-
if (requirement.scheme !== "exact") {
|
|
130
|
-
throw new Error(`Unsupported payment scheme: "${requirement.scheme}". Only "exact" is supported.`);
|
|
131
|
-
}
|
|
132
|
-
if (requirement.network !== "starknet-mainnet") {
|
|
133
|
-
throw new Error(`Unsupported network: "${requirement.network}". Only "starknet-mainnet" is supported.`);
|
|
134
|
-
}
|
|
135
|
-
if (!requirement.payTo) {
|
|
136
|
-
throw new Error("Invalid payment requirement: missing payTo address");
|
|
137
|
-
}
|
|
138
|
-
if (!requirement.asset) {
|
|
139
|
-
throw new Error("Invalid payment requirement: missing asset address");
|
|
140
|
-
}
|
|
141
|
-
if (typeof requirement.maxTimeoutSeconds !== "number" || requirement.maxTimeoutSeconds <= 0) {
|
|
142
|
-
throw new Error("Invalid payment requirement: maxTimeoutSeconds must be a positive number");
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
const parsedAmount = BigInt(requirement.maxAmountRequired);
|
|
146
|
-
if (parsedAmount <= 0n) {
|
|
147
|
-
throw new Error("non-positive");
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
throw new Error(`Invalid payment requirement: maxAmountRequired must be a positive integer, got "${requirement.maxAmountRequired}"`);
|
|
152
|
-
}
|
|
153
|
-
return requirement;
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Validate payment requirement against client configuration limits.
|
|
157
|
-
* Throws if the payment would exceed maxPaymentAmount or recipient is not whitelisted.
|
|
158
|
-
*/
|
|
159
|
-
validateRequirement(requirement) {
|
|
160
|
-
// Validate payment amount
|
|
161
|
-
if (this.config.maxPaymentAmount) {
|
|
162
|
-
const maxBaseUnits = humanUsdcToBaseUnits(this.config.maxPaymentAmount, USDC_DECIMALS);
|
|
163
|
-
const requiredAmount = BigInt(requirement.maxAmountRequired);
|
|
164
|
-
if (requiredAmount > maxBaseUnits) {
|
|
165
|
-
const requiredHuman = (Number(requiredAmount) / 10 ** USDC_DECIMALS).toFixed(USDC_DECIMALS);
|
|
166
|
-
throw new Error(`Payment amount ${requiredHuman} USDC exceeds maximum allowed ${this.config.maxPaymentAmount} USDC`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
// Validate recipient whitelist
|
|
170
|
-
if (this.config.allowedRecipients && this.config.allowedRecipients.length > 0) {
|
|
171
|
-
const normalizedPayTo = requirement.payTo.toLowerCase();
|
|
172
|
-
const isAllowed = this.config.allowedRecipients.some((addr) => addr.toLowerCase() === normalizedPayTo);
|
|
173
|
-
if (!isAllowed) {
|
|
174
|
-
throw new Error(`Recipient ${requirement.payTo} is not in the allowed recipients list`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
// Validate asset is USDC
|
|
178
|
-
const normalizedAsset = requirement.asset.toLowerCase().replace(/^0x0+/, "0x");
|
|
179
|
-
const normalizedUsdc = USDC_MAINNET.toLowerCase().replace(/^0x0+/, "0x");
|
|
180
|
-
if (normalizedAsset !== normalizedUsdc) {
|
|
181
|
-
throw new Error(`Unsupported asset: ${requirement.asset}. Only USDC (${USDC_MAINNET}) is supported.`);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Sign a SNIP-12 typed data payment message for the given requirement.
|
|
186
|
-
* Returns a PaymentPayload ready to be sent as the X-PAYMENT header.
|
|
187
|
-
*/
|
|
188
|
-
async signPayment(requirement) {
|
|
189
|
-
const nonce = generateNonce();
|
|
190
|
-
const validUntil = Math.floor(Date.now() / 1000) + requirement.maxTimeoutSeconds;
|
|
191
|
-
const typedData = buildX402TypedData({
|
|
192
|
-
from_address: this.account.address,
|
|
193
|
-
to_address: requirement.payTo,
|
|
194
|
-
amount: requirement.maxAmountRequired,
|
|
195
|
-
asset: requirement.asset,
|
|
196
|
-
valid_until: String(validUntil),
|
|
197
|
-
nonce,
|
|
198
|
-
});
|
|
199
|
-
const signature = await this.account.signMessage(typedData);
|
|
200
|
-
// Normalize signature to { r, s } format
|
|
201
|
-
const normalizedSig = normalizeX402Signature(signature);
|
|
202
|
-
return {
|
|
203
|
-
x402Version: 1,
|
|
204
|
-
scheme: "exact",
|
|
205
|
-
network: "starknet-mainnet",
|
|
206
|
-
payload: {
|
|
207
|
-
signature: normalizedSig,
|
|
208
|
-
fromAddress: this.account.address,
|
|
209
|
-
toAddress: requirement.payTo,
|
|
210
|
-
amount: requirement.maxAmountRequired,
|
|
211
|
-
asset: requirement.asset,
|
|
212
|
-
validUntil,
|
|
213
|
-
nonce,
|
|
214
|
-
},
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Retry the original request with the X-PAYMENT header containing the signed payment.
|
|
219
|
-
*/
|
|
220
|
-
async retryWithPayment(url, init, payment) {
|
|
221
|
-
const existingHeaders = init?.headers ?? {};
|
|
222
|
-
const headers = {
|
|
223
|
-
...existingHeaders,
|
|
224
|
-
[this.config.headerName]: JSON.stringify(payment),
|
|
225
|
-
};
|
|
226
|
-
return this.fetchFn(url, {
|
|
227
|
-
...init,
|
|
228
|
-
headers,
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Convert human-readable USDC amount to base units using string arithmetic (no float).
|
|
234
|
-
*/
|
|
235
|
-
function humanUsdcToBaseUnits(amount, decimals) {
|
|
236
|
-
const [whole, frac = ""] = amount.trim().split(".");
|
|
237
|
-
const fracPadded = (frac + "0".repeat(decimals)).slice(0, decimals);
|
|
238
|
-
return BigInt((whole || "0") + fracPadded);
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Generate a unique nonce for replay protection.
|
|
242
|
-
* Uses crypto.randomUUID when available, falls back to timestamp + random.
|
|
243
|
-
*/
|
|
244
|
-
function generateNonce() {
|
|
245
|
-
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
246
|
-
return globalThis.crypto.randomUUID();
|
|
247
|
-
}
|
|
248
|
-
return `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Normalize signature from account.signMessage() to { r, s } string format.
|
|
252
|
-
* Handles WeierstrassSignatureType ({r, s} as bigint) and ArraySignatureType ([r, s]).
|
|
253
|
-
*/
|
|
254
|
-
function normalizeX402Signature(signature) {
|
|
255
|
-
if (Array.isArray(signature)) {
|
|
256
|
-
if (signature.length < 2) {
|
|
257
|
-
throw new Error(`Array signature must have at least 2 elements, got ${signature.length}`);
|
|
258
|
-
}
|
|
259
|
-
return { r: String(signature[0]), s: String(signature[1]) };
|
|
260
|
-
}
|
|
261
|
-
if (signature && typeof signature === "object" && "r" in signature && "s" in signature) {
|
|
262
|
-
const sig = signature;
|
|
263
|
-
if (sig.r == null || sig.s == null) {
|
|
264
|
-
throw new Error("Invalid signature object: r and s must be non-null");
|
|
265
|
-
}
|
|
266
|
-
return { r: String(sig.r), s: String(sig.s) };
|
|
267
|
-
}
|
|
268
|
-
throw new Error("Unrecognized signature format from account.signMessage()");
|
|
269
|
-
}
|
|
270
|
-
//# sourceMappingURL=client.js.map
|
package/dist/x402/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/x402/client.ts"],"names":[],"mappings":"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"}
|
package/dist/x402/index.d.ts
DELETED
package/dist/x402/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/x402/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,KAAK,qBAAqB,GAC3B,MAAM,aAAa,CAAC"}
|
package/dist/x402/index.js
DELETED
package/dist/x402/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/x402/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,kBAAkB,GAEnB,MAAM,aAAa,CAAC"}
|