@nibgate/sdk 0.2.8 → 0.2.9

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/nibgate.js CHANGED
@@ -33,32 +33,156 @@ var Nibgate = (() => {
33
33
  }
34
34
  });
35
35
 
36
+ // src/browser/schemes/batch-scheme.js
37
+ function supportsBatching(requirements) {
38
+ const extra = requirements.extra;
39
+ if (!extra) return false;
40
+ return extra.name === CIRCLE_BATCHING_NAME && extra.version === CIRCLE_BATCHING_VERSION;
41
+ }
42
+ function getVerifyingContract(requirements) {
43
+ if (!supportsBatching(requirements)) return void 0;
44
+ return requirements.extra?.verifyingContract;
45
+ }
46
+ function createNonce() {
47
+ const bytes = new Uint8Array(32);
48
+ crypto.getRandomValues(bytes);
49
+ return "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
50
+ }
51
+ function getAddress(value) {
52
+ return value && typeof value === "string" && value.startsWith("0x") ? value.toLowerCase() : value;
53
+ }
54
+ var CIRCLE_BATCHING_NAME, CIRCLE_BATCHING_VERSION, GATEWAY_MIN_AUTH_VALIDITY_SECONDS, GATEWAY_AUTH_VALIDITY_WINDOW_SECONDS, authorizationTypes, BatchEvmScheme;
55
+ var init_batch_scheme = __esm({
56
+ "src/browser/schemes/batch-scheme.js"() {
57
+ CIRCLE_BATCHING_NAME = "GatewayWalletBatched";
58
+ CIRCLE_BATCHING_VERSION = "1";
59
+ GATEWAY_MIN_AUTH_VALIDITY_SECONDS = 7 * 24 * 60 * 60;
60
+ GATEWAY_AUTH_VALIDITY_WINDOW_SECONDS = GATEWAY_MIN_AUTH_VALIDITY_SECONDS + 100;
61
+ authorizationTypes = {
62
+ TransferWithAuthorization: [
63
+ { name: "from", type: "address" },
64
+ { name: "to", type: "address" },
65
+ { name: "value", type: "uint256" },
66
+ { name: "validAfter", type: "uint256" },
67
+ { name: "validBefore", type: "uint256" },
68
+ { name: "nonce", type: "bytes32" }
69
+ ]
70
+ };
71
+ BatchEvmScheme = class {
72
+ constructor(signer) {
73
+ this.signer = signer;
74
+ this.scheme = CIRCLE_BATCHING_NAME;
75
+ this._beforeHooks = [];
76
+ this._afterHooks = [];
77
+ this._failureHooks = [];
78
+ }
79
+ onBeforePaymentCreation(hook) {
80
+ this._beforeHooks.push(hook);
81
+ return this;
82
+ }
83
+ onAfterPaymentCreation(hook) {
84
+ this._afterHooks.push(hook);
85
+ return this;
86
+ }
87
+ onPaymentCreationFailure(hook) {
88
+ this._failureHooks.push(hook);
89
+ return this;
90
+ }
91
+ async createPaymentPayload(x402Version, paymentRequirements) {
92
+ const context = {
93
+ paymentRequired: { x402Version, accepts: [paymentRequirements] },
94
+ selectedRequirements: paymentRequirements
95
+ };
96
+ for (const hook of this._beforeHooks) {
97
+ const result = await hook(context);
98
+ if (result && result.abort) {
99
+ throw new Error("Payment creation aborted: " + result.reason);
100
+ }
101
+ }
102
+ try {
103
+ if (!supportsBatching(paymentRequirements)) {
104
+ throw new Error(
105
+ 'BatchEvmScheme can only handle Circle batching options. Expected extra.name="' + CIRCLE_BATCHING_NAME + '" and extra.version="' + CIRCLE_BATCHING_VERSION + '"'
106
+ );
107
+ }
108
+ const verifyingContract = getVerifyingContract(paymentRequirements);
109
+ if (!verifyingContract) {
110
+ throw new Error(
111
+ "Circle batching option missing extra.verifyingContract (GatewayWallet address)"
112
+ );
113
+ }
114
+ const nonce = createNonce();
115
+ const now = Math.floor(Date.now() / 1e3);
116
+ const validityWindowSeconds = Math.max(
117
+ paymentRequirements.maxTimeoutSeconds || 0,
118
+ GATEWAY_AUTH_VALIDITY_WINDOW_SECONDS
119
+ );
120
+ const authorization = {
121
+ from: getAddress(this.signer.address),
122
+ to: getAddress(paymentRequirements.payTo),
123
+ value: paymentRequirements.amount,
124
+ validAfter: String(now - 600),
125
+ validBefore: String(now + validityWindowSeconds),
126
+ nonce
127
+ };
128
+ const signature = await this.signAuthorization(authorization, paymentRequirements, verifyingContract);
129
+ const payload = { authorization, signature };
130
+ const result = { x402Version, payload };
131
+ const createdContext = { ...context, paymentPayload: result };
132
+ for (const hook of this._afterHooks) {
133
+ try {
134
+ await hook(createdContext);
135
+ } catch {
136
+ }
137
+ }
138
+ return result;
139
+ } catch (error) {
140
+ const failureContext = { ...context, error };
141
+ for (const hook of this._failureHooks) {
142
+ const result = await hook(failureContext);
143
+ if (result && result.recovered) {
144
+ return { x402Version: result.payload.x402Version, payload: result.payload.payload };
145
+ }
146
+ }
147
+ throw error;
148
+ }
149
+ }
150
+ async signAuthorization(authorization, requirements, verifyingContract) {
151
+ if (!requirements.network.startsWith("eip155:")) {
152
+ throw new Error('BatchEvmScheme: unsupported network format "' + requirements.network + '". Expected "eip155:<chainId>"');
153
+ }
154
+ const chainId = parseInt(requirements.network.split(":")[1], 10);
155
+ const domain = {
156
+ name: CIRCLE_BATCHING_NAME,
157
+ version: CIRCLE_BATCHING_VERSION,
158
+ chainId,
159
+ verifyingContract: getAddress(verifyingContract)
160
+ };
161
+ const message = {
162
+ from: getAddress(authorization.from),
163
+ to: getAddress(authorization.to),
164
+ value: BigInt(authorization.value),
165
+ validAfter: BigInt(authorization.validAfter),
166
+ validBefore: BigInt(authorization.validBefore),
167
+ nonce: authorization.nonce
168
+ };
169
+ const typedData = {
170
+ domain,
171
+ types: authorizationTypes,
172
+ primaryType: "TransferWithAuthorization",
173
+ message
174
+ };
175
+ return this.signer.signTypedData(typedData);
176
+ }
177
+ };
178
+ }
179
+ });
180
+
36
181
  // src/browser/gateway.js
37
182
  var gateway_exports = {};
38
183
  __export(gateway_exports, {
39
184
  createCircleGatewayBrowserAdapter: () => createCircleGatewayBrowserAdapter
40
185
  });
41
- async function getCircleClient(options = {}) {
42
- if (cachedCircleModule) return cachedCircleModule;
43
- if (options.clientModule) {
44
- cachedCircleModule = options.clientModule;
45
- return cachedCircleModule;
46
- }
47
- const moduleUrl = options.clientModuleUrl || "@circle-fin/x402-batching/client";
48
- try {
49
- cachedCircleModule = await import(moduleUrl);
50
- return cachedCircleModule;
51
- } catch (error) {
52
- if (!options.clientModuleUrl) {
53
- throw new Error(
54
- `Could not load @circle-fin/x402-batching/client from node_modules. Provide a clientModuleUrl option (e.g. "https://esm.sh/@circle-fin/x402-batching@3.2.0/client?bundle") to load from CDN. Original error: ${error.message}`
55
- );
56
- }
57
- throw new Error(
58
- `Could not load Circle Gateway client from CDN: ${error.message}. Check that ${options.clientModuleUrl} is reachable.`
59
- );
60
- }
61
- }
62
186
  function encodeBase64(value) {
63
187
  const text = typeof value === "string" ? value : stringifyJson(value);
64
188
  if (typeof Buffer !== "undefined") return Buffer.from(text).toString("base64");
@@ -73,9 +197,7 @@ var Nibgate = (() => {
73
197
  if (!signer?.address || typeof signer.signTypedData !== "function") {
74
198
  throw new Error("Circle Gateway browser adapter requires an EVM signer with address and signTypedData.");
75
199
  }
76
- const circleClientModule = await getCircleClient(options);
77
- const { BatchEvmScheme } = circleClientModule;
78
- const scheme = new BatchEvmScheme(signer);
200
+ const scheme = options.clientModule?.BatchEvmScheme ? new options.clientModule.BatchEvmScheme(signer) : new BatchEvmScheme(signer);
79
201
  const network = options.network || options.chainId && `eip155:${options.chainId}` || "eip155:5042002";
80
202
  function parsePaymentRequired(input) {
81
203
  if (input && typeof input === "object") return input;
@@ -131,11 +253,10 @@ var Nibgate = (() => {
131
253
  }
132
254
  };
133
255
  }
134
- var cachedCircleModule;
135
256
  var init_gateway = __esm({
136
257
  "src/browser/gateway.js"() {
258
+ init_batch_scheme();
137
259
  init_json();
138
- cachedCircleModule = null;
139
260
  }
140
261
  });
141
262
 
@@ -804,7 +925,6 @@ var Nibgate = (() => {
804
925
  const gateway = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
805
926
  return gateway.createCircleGatewayBrowserAdapter(options);
806
927
  }
807
- var DEFAULT_CIRCLE_CDN = "https://esm.sh/@circle-fin/x402-batching@3.2.0/client?bundle";
808
928
  var HOSTED_PAY_URL = "https://api.nibgate.xyz/api/hub/pay";
809
929
  function resolveAccessPath(resource, options) {
810
930
  if (options.hosted || options.accessPath === "hosted") return HOSTED_PAY_URL;
@@ -903,8 +1023,7 @@ var Nibgate = (() => {
903
1023
  address: walletAddress,
904
1024
  signTypedData: (typedData) => evm.request({ method: "eth_signTypedData_v4", params: [walletAddress, stringifyJson(typedData)] })
905
1025
  },
906
- clientModule: options.circleClientModule,
907
- clientModuleUrl: options.circleClientModuleUrl || DEFAULT_CIRCLE_CDN
1026
+ clientModule: options.circleClientModule
908
1027
  });
909
1028
  return gatewayWallet.pay(input);
910
1029
  }
@@ -921,6 +1040,9 @@ var Nibgate = (() => {
921
1040
  challengeMessage: options.challengeMessage || "Gateway payment required. Connect your wallet to continue...",
922
1041
  paymentMessage: options.paymentMessage || "Approve the Gateway payment proof in your wallet...",
923
1042
  successMessage: options.successMessage || `Unlocked ${item.resource.title || "content"}.`,
1043
+ method: options.method,
1044
+ headers: options.headers,
1045
+ body: options.body,
924
1046
  checkout,
925
1047
  onStatus: setStatus
926
1048
  });
@@ -970,7 +1092,6 @@ var Nibgate = (() => {
970
1092
  return createEvmGatewayUnlock(resource, {
971
1093
  ...options,
972
1094
  hosted: true,
973
- circleClientModuleUrl: options.circleClientModuleUrl || DEFAULT_CIRCLE_CDN,
974
1095
  noWalletMessage: options.noWalletMessage || "Install MetaMask or another EVM wallet to unlock premium content."
975
1096
  });
976
1097
  }