@nibgate/sdk 0.1.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/README.md +605 -0
- package/package.json +58 -0
- package/src/browser/env.js +3 -0
- package/src/browser/events.js +57 -0
- package/src/browser/gateway.js +89 -0
- package/src/browser/index.js +710 -0
- package/src/browser/json.js +8 -0
- package/src/browser/reputation.js +161 -0
- package/src/browser/storage.js +68 -0
- package/src/browser/tracking.js +42 -0
- package/src/browser/transfer.js +53 -0
- package/src/core/payment.js +8 -0
- package/src/core/rating.js +28 -0
- package/src/core/resource.js +143 -0
- package/src/core/settings.js +47 -0
- package/src/index.d.ts +423 -0
- package/src/index.js +1 -0
- package/src/server/access.js +217 -0
- package/src/server/actor.js +23 -0
- package/src/server/challenge.js +51 -0
- package/src/server/env.js +3 -0
- package/src/server/gateway.js +186 -0
- package/src/server/hub.js +36 -0
- package/src/server/index.js +15 -0
- package/src/server/manifest.js +19 -0
- package/src/server/presets.js +14 -0
- package/src/server/proof.js +73 -0
- package/src/server/response.js +9 -0
- package/src/server/runtime.js +39 -0
- package/src/server.d.ts +212 -0
- package/src/server.js +1 -0
- package/src/testing.d.ts +23 -0
- package/src/testing.js +56 -0
- package/src/tracking.d.ts +18 -0
- package/src/tracking.js +1 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { browserWindow } from './env.js';
|
|
2
|
+
import { normalizeResource } from '../core/resource.js';
|
|
3
|
+
|
|
4
|
+
export function queueEvent(eventName, payload) {
|
|
5
|
+
const win = browserWindow();
|
|
6
|
+
if (!win) return false;
|
|
7
|
+
win.__nibgateClientQueue = win.__nibgateClientQueue || [];
|
|
8
|
+
win.__nibgateClientQueue.push({ eventName, payload });
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function flushQueue() {
|
|
13
|
+
const win = browserWindow();
|
|
14
|
+
if (!win?.nibgateHub?.track || !Array.isArray(win.__nibgateClientQueue)) return false;
|
|
15
|
+
const queue = win.__nibgateClientQueue.splice(0);
|
|
16
|
+
queue.forEach((entry) => {
|
|
17
|
+
win.nibgateHub.track(entry.eventName, entry.payload);
|
|
18
|
+
});
|
|
19
|
+
return queue.length > 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function startQueueFlush() {
|
|
23
|
+
const win = browserWindow();
|
|
24
|
+
if (!win || win.__nibgateClientFlushStarted) return;
|
|
25
|
+
win.__nibgateClientFlushStarted = true;
|
|
26
|
+
let attempts = 0;
|
|
27
|
+
const timer = win.setInterval(() => {
|
|
28
|
+
attempts += 1;
|
|
29
|
+
flushQueue();
|
|
30
|
+
if (win.nibgateHub?.track || attempts >= 80) {
|
|
31
|
+
win.clearInterval(timer);
|
|
32
|
+
win.__nibgateClientFlushStarted = false;
|
|
33
|
+
}
|
|
34
|
+
}, 250);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function emit(eventName, payload = {}) {
|
|
38
|
+
const win = browserWindow();
|
|
39
|
+
if (!win) return false;
|
|
40
|
+
|
|
41
|
+
if (win.nibgateHub?.track) {
|
|
42
|
+
win.nibgateHub.track(eventName, payload);
|
|
43
|
+
flushQueue();
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
queueEvent(eventName, payload);
|
|
48
|
+
startQueueFlush();
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function payloadWithResource(resource, extra = {}) {
|
|
53
|
+
return {
|
|
54
|
+
...extra,
|
|
55
|
+
resource: normalizeResource(resource)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { stringifyJson } from './json.js';
|
|
2
|
+
|
|
3
|
+
function encodeBase64(value) {
|
|
4
|
+
const text = typeof value === 'string' ? value : stringifyJson(value);
|
|
5
|
+
if (typeof Buffer !== 'undefined') return Buffer.from(text).toString('base64');
|
|
6
|
+
return btoa(unescape(encodeURIComponent(text)));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function decodeBase64(value) {
|
|
10
|
+
if (typeof Buffer !== 'undefined') return Buffer.from(value, 'base64').toString('utf8');
|
|
11
|
+
return decodeURIComponent(escape(atob(value)));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function createCircleGatewayBrowserAdapter(options = {}) {
|
|
15
|
+
const signer = options.signer || await options.getSigner?.();
|
|
16
|
+
if (!signer?.address || typeof signer.signTypedData !== 'function') {
|
|
17
|
+
throw new Error('Circle Gateway browser adapter requires an EVM signer with address and signTypedData.');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const circleClientModule = options.clientModule || (options.clientModuleUrl
|
|
21
|
+
? await import(options.clientModuleUrl)
|
|
22
|
+
: await import('@circle-fin/x402-batching/client'));
|
|
23
|
+
const { BatchEvmScheme } = circleClientModule;
|
|
24
|
+
const scheme = new BatchEvmScheme(signer);
|
|
25
|
+
const network = options.network || options.chainId && `eip155:${options.chainId}` || 'eip155:5042002';
|
|
26
|
+
|
|
27
|
+
function parsePaymentRequired(input) {
|
|
28
|
+
if (input && typeof input === 'object') return input;
|
|
29
|
+
if (!input || typeof input !== 'string') throw new Error('Missing PAYMENT-REQUIRED header.');
|
|
30
|
+
return JSON.parse(decodeBase64(input));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function selectGatewayRequirement(paymentRequired) {
|
|
34
|
+
const accepts = Array.isArray(paymentRequired?.accepts) ? paymentRequired.accepts : [];
|
|
35
|
+
const selected = accepts.find((option) => {
|
|
36
|
+
const extra = option.extra || {};
|
|
37
|
+
return option.network === network
|
|
38
|
+
&& extra.name === 'GatewayWalletBatched'
|
|
39
|
+
&& extra.version === '1'
|
|
40
|
+
&& typeof extra.verifyingContract === 'string';
|
|
41
|
+
}) || accepts.find((option) => {
|
|
42
|
+
const extra = option.extra || {};
|
|
43
|
+
return extra.name === 'GatewayWalletBatched'
|
|
44
|
+
&& extra.version === '1'
|
|
45
|
+
&& typeof extra.verifyingContract === 'string';
|
|
46
|
+
});
|
|
47
|
+
if (!selected) {
|
|
48
|
+
const networks = accepts.map((option) => option.network).filter(Boolean).join(', ') || 'none';
|
|
49
|
+
const hasGatewayExtra = accepts.some((option) => {
|
|
50
|
+
const extra = option.extra || {};
|
|
51
|
+
return extra.name === 'GatewayWalletBatched' && extra.version === '1' && typeof extra.verifyingContract === 'string';
|
|
52
|
+
});
|
|
53
|
+
throw new Error(
|
|
54
|
+
hasGatewayExtra
|
|
55
|
+
? `No Circle Gateway batching payment option found for ${network}. Server returned networks: ${networks}.`
|
|
56
|
+
: `The payment challenge is not a Circle Gateway batching challenge. Configure the creator access route with createCircleGatewayServer(...) or createNibgateServer({ paymentMode: 'circle-gateway', network: '${network}' }).`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return selected;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
signer,
|
|
64
|
+
network,
|
|
65
|
+
async pay({ paymentRequiredHeader, challenge }) {
|
|
66
|
+
const paymentRequired = parsePaymentRequired(paymentRequiredHeader || challenge);
|
|
67
|
+
const accepted = selectGatewayRequirement(paymentRequired);
|
|
68
|
+
const x402Version = paymentRequired.x402Version ?? 2;
|
|
69
|
+
const paymentPayload = await scheme.createPaymentPayload(x402Version, accepted);
|
|
70
|
+
const paymentSignature = encodeBase64({
|
|
71
|
+
...paymentPayload,
|
|
72
|
+
resource: paymentRequired.resource,
|
|
73
|
+
accepted
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
paymentSignature,
|
|
77
|
+
signature: paymentSignature,
|
|
78
|
+
metadata: {
|
|
79
|
+
paymentProvider: 'circle-gateway',
|
|
80
|
+
network: accepted.network,
|
|
81
|
+
payer: signer.address,
|
|
82
|
+
recipient: accepted.payTo || accepted.recipient,
|
|
83
|
+
amount: accepted.amount,
|
|
84
|
+
currency: accepted.asset
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|