apinow-sdk 0.28.0 → 0.28.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/index.d.ts +1 -0
- package/dist/index.js +45 -12
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { x402Client, wrapFetchWithPayment } from '@x402/fetch';
|
|
|
2
2
|
import { registerExactEvmScheme } from '@x402/evm/exact/client';
|
|
3
3
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
4
4
|
const APINOW_BASE = 'https://apinow.fun';
|
|
5
|
+
export const APINOW_SDK_VERSION = '0.28.2';
|
|
5
6
|
function isServerConfig(c) {
|
|
6
7
|
return 'privateKey' in c && typeof c.privateKey === 'string';
|
|
7
8
|
}
|
|
@@ -86,10 +87,31 @@ export function createClient(config) {
|
|
|
86
87
|
async function signAuthHeader() {
|
|
87
88
|
const issuedAt = new Date().toISOString();
|
|
88
89
|
const nonce = Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
// Single-line format: Chrome's fetch() rejects header values containing
|
|
91
|
+
// raw newlines ("Failed to execute 'fetch' on 'Window': Invalid value").
|
|
92
|
+
// Server parses via regex so space-separated works identically.
|
|
93
|
+
const message = `APINow auth | address: ${address} | issuedAt: ${issuedAt} | nonce: ${nonce}`;
|
|
94
|
+
const signature = String(await signMessage(message));
|
|
95
|
+
const authorization = `Bearer ${message}||${signature}||${address}`;
|
|
96
|
+
// Guard against any character that Chrome's fetch() rejects in header
|
|
97
|
+
// values — pre-throw with a readable message rather than letting the
|
|
98
|
+
// browser fail with the opaque "Invalid value" error.
|
|
99
|
+
const bad = /[\r\n\0]/;
|
|
100
|
+
if (bad.test(authorization)) {
|
|
101
|
+
const offender = bad.exec(authorization)?.[0];
|
|
102
|
+
// eslint-disable-next-line no-console
|
|
103
|
+
console.error('[apinow-sdk] bad char in Authorization header', {
|
|
104
|
+
messageLen: message.length,
|
|
105
|
+
sigLen: signature.length,
|
|
106
|
+
offenderCode: offender?.charCodeAt(0),
|
|
107
|
+
messagePreview: message.slice(0, 80),
|
|
108
|
+
});
|
|
109
|
+
throw new Error(`apinow-sdk: signed Authorization header contains a control char (code ${offender?.charCodeAt(0)}). ` +
|
|
110
|
+
`This usually means the wallet signer returned a malformed signature. ` +
|
|
111
|
+
`sigLen=${signature.length} messageLen=${message.length}`);
|
|
112
|
+
}
|
|
91
113
|
return {
|
|
92
|
-
Authorization:
|
|
114
|
+
Authorization: authorization,
|
|
93
115
|
'x-wallet-address': address,
|
|
94
116
|
};
|
|
95
117
|
}
|
|
@@ -99,15 +121,26 @@ export function createClient(config) {
|
|
|
99
121
|
*/
|
|
100
122
|
async function authedFetch(url, init = {}) {
|
|
101
123
|
const authHeaders = await signAuthHeader();
|
|
102
|
-
const
|
|
103
|
-
...init,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
124
|
+
const headers = {
|
|
125
|
+
...(init.body ? { 'Content-Type': 'application/json' } : {}),
|
|
126
|
+
...authHeaders,
|
|
127
|
+
...init.headers,
|
|
128
|
+
};
|
|
129
|
+
try {
|
|
130
|
+
return await fetch(url, { ...init, headers });
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
// eslint-disable-next-line no-console
|
|
134
|
+
console.error('[apinow-sdk] authedFetch failed', {
|
|
135
|
+
sdkVersion: APINOW_SDK_VERSION,
|
|
136
|
+
url,
|
|
137
|
+
method: init.method || 'GET',
|
|
138
|
+
headerKeys: Object.keys(headers),
|
|
139
|
+
headerLens: Object.fromEntries(Object.entries(headers).map(([k, v]) => [k, String(v).length])),
|
|
140
|
+
err: err?.message,
|
|
141
|
+
});
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
111
144
|
}
|
|
112
145
|
async function authedJson(url, init = {}) {
|
|
113
146
|
const res = await authedFetch(url, init);
|
package/package.json
CHANGED