@rhinestone/1auth 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/dist/chunk-UXYKIMGZ.mjs +482 -0
- package/dist/chunk-UXYKIMGZ.mjs.map +1 -0
- package/dist/client-C1inywuT.d.mts +777 -0
- package/dist/client-C1inywuT.d.ts +777 -0
- package/dist/index.d.mts +267 -0
- package/dist/index.d.ts +267 -0
- package/dist/index.js +2701 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2213 -0
- package/dist/index.mjs.map +1 -0
- package/dist/provider-Dgh51NRc.d.mts +24 -0
- package/dist/provider-q7M728Mn.d.ts +24 -0
- package/dist/react.d.mts +41 -0
- package/dist/react.d.ts +41 -0
- package/dist/react.js +228 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +193 -0
- package/dist/react.mjs.map +1 -0
- package/dist/server.d.mts +81 -0
- package/dist/server.d.ts +81 -0
- package/dist/server.js +142 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +116 -0
- package/dist/server.mjs.map +1 -0
- package/dist/wagmi.d.mts +15 -0
- package/dist/wagmi.d.ts +15 -0
- package/dist/wagmi.js +569 -0
- package/dist/wagmi.js.map +1 -0
- package/dist/wagmi.mjs +176 -0
- package/dist/wagmi.mjs.map +1 -0
- package/package.json +61 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/server.ts
|
|
21
|
+
var server_exports = {};
|
|
22
|
+
__export(server_exports, {
|
|
23
|
+
createSignIntentHandler: () => createSignIntentHandler,
|
|
24
|
+
signIntent: () => signIntent
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(server_exports);
|
|
27
|
+
var import_crypto = require("crypto");
|
|
28
|
+
function createCanonicalMessage(data) {
|
|
29
|
+
return JSON.stringify({
|
|
30
|
+
merchantId: data.merchantId,
|
|
31
|
+
targetChain: data.targetChain,
|
|
32
|
+
calls: data.calls.map((c) => ({
|
|
33
|
+
to: c.to.toLowerCase(),
|
|
34
|
+
data: (c.data || "0x").toLowerCase(),
|
|
35
|
+
value: c.value || "0",
|
|
36
|
+
label: c.label || "",
|
|
37
|
+
sublabel: c.sublabel || ""
|
|
38
|
+
})),
|
|
39
|
+
username: data.username,
|
|
40
|
+
accountAddress: data.accountAddress?.toLowerCase(),
|
|
41
|
+
nonce: data.nonce,
|
|
42
|
+
expiresAt: data.expiresAt
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function signMessage(message, privateKeyBase64) {
|
|
46
|
+
const privateKeyBuffer = Buffer.from(privateKeyBase64, "base64");
|
|
47
|
+
const signature = (0, import_crypto.sign)(null, Buffer.from(message), {
|
|
48
|
+
key: privateKeyBuffer,
|
|
49
|
+
format: "der",
|
|
50
|
+
type: "pkcs8"
|
|
51
|
+
});
|
|
52
|
+
return signature.toString("base64");
|
|
53
|
+
}
|
|
54
|
+
function signIntent(params, config) {
|
|
55
|
+
const { username, accountAddress, targetChain, calls, tokenRequests } = params;
|
|
56
|
+
const { merchantId, privateKey, expiryMs = 5 * 60 * 1e3 } = config;
|
|
57
|
+
if (!merchantId || !privateKey) {
|
|
58
|
+
throw new Error("Missing merchantId or privateKey in config");
|
|
59
|
+
}
|
|
60
|
+
if (!username && !accountAddress) {
|
|
61
|
+
throw new Error("Either username or accountAddress is required");
|
|
62
|
+
}
|
|
63
|
+
if (!targetChain || !calls?.length) {
|
|
64
|
+
throw new Error("targetChain and calls are required");
|
|
65
|
+
}
|
|
66
|
+
const nonce = crypto.randomUUID();
|
|
67
|
+
const expiresAt = Date.now() + expiryMs;
|
|
68
|
+
const intentData = {
|
|
69
|
+
merchantId,
|
|
70
|
+
targetChain,
|
|
71
|
+
calls,
|
|
72
|
+
username,
|
|
73
|
+
accountAddress,
|
|
74
|
+
nonce,
|
|
75
|
+
expiresAt
|
|
76
|
+
};
|
|
77
|
+
const message = createCanonicalMessage(intentData);
|
|
78
|
+
const signature = signMessage(message, privateKey);
|
|
79
|
+
return {
|
|
80
|
+
...intentData,
|
|
81
|
+
signature,
|
|
82
|
+
tokenRequests
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function createSignIntentHandler(config) {
|
|
86
|
+
return async function handler(request) {
|
|
87
|
+
if (!config.merchantId || !config.privateKey) {
|
|
88
|
+
console.error("Missing MERCHANT_ID or MERCHANT_PRIVATE_KEY");
|
|
89
|
+
return Response.json(
|
|
90
|
+
{ error: "Server misconfiguration: missing merchant credentials" },
|
|
91
|
+
{ status: 500 }
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const body = await request.json();
|
|
96
|
+
const { targetChain, calls, username, accountAddress, tokenRequests } = body;
|
|
97
|
+
if (!targetChain || typeof targetChain !== "number") {
|
|
98
|
+
return Response.json(
|
|
99
|
+
{ error: "targetChain is required and must be a number" },
|
|
100
|
+
{ status: 400 }
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
if (!calls || !Array.isArray(calls) || calls.length === 0) {
|
|
104
|
+
return Response.json(
|
|
105
|
+
{ error: "calls is required and must be a non-empty array" },
|
|
106
|
+
{ status: 400 }
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
if (!username && !accountAddress) {
|
|
110
|
+
return Response.json(
|
|
111
|
+
{ error: "Either username or accountAddress is required" },
|
|
112
|
+
{ status: 400 }
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
for (const call of calls) {
|
|
116
|
+
if (!call.to || !/^0x[a-fA-F0-9]{40}$/.test(call.to)) {
|
|
117
|
+
return Response.json(
|
|
118
|
+
{ error: "Each call must have a valid 'to' address" },
|
|
119
|
+
{ status: 400 }
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const signedIntent = signIntent(
|
|
124
|
+
{ username, accountAddress, targetChain, calls, tokenRequests },
|
|
125
|
+
config
|
|
126
|
+
);
|
|
127
|
+
return Response.json(signedIntent);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error("Error signing intent:", error);
|
|
130
|
+
return Response.json(
|
|
131
|
+
{ error: "Failed to sign intent" },
|
|
132
|
+
{ status: 500 }
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
138
|
+
0 && (module.exports = {
|
|
139
|
+
createSignIntentHandler,
|
|
140
|
+
signIntent
|
|
141
|
+
});
|
|
142
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * Server-side utilities for 1auth SDK\n * Use these in Next.js API routes or server actions\n */\n\nimport { sign } from \"crypto\";\n\nexport interface MerchantConfig {\n /** Merchant ID from registration */\n merchantId: string;\n /** Ed25519 private key (base64 encoded) */\n privateKey: string;\n /** Intent expiry time in ms (default: 5 minutes) */\n expiryMs?: number;\n}\n\nexport interface IntentCall {\n to: string;\n data?: string;\n value?: string;\n label?: string;\n sublabel?: string;\n}\n\nexport interface SignIntentParams {\n username?: string;\n accountAddress?: string;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\nexport interface SignedIntent {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n signature: string;\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\n/**\n * Create canonical message for signing\n * Must match the format expected by passkey service\n */\nfunction createCanonicalMessage(data: {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n}): string {\n return JSON.stringify({\n merchantId: data.merchantId,\n targetChain: data.targetChain,\n calls: data.calls.map((c) => ({\n to: c.to.toLowerCase(),\n data: (c.data || \"0x\").toLowerCase(),\n value: c.value || \"0\",\n label: c.label || \"\",\n sublabel: c.sublabel || \"\",\n })),\n username: data.username,\n accountAddress: data.accountAddress?.toLowerCase(),\n nonce: data.nonce,\n expiresAt: data.expiresAt,\n });\n}\n\n/**\n * Sign an intent with Ed25519 private key\n */\nfunction signMessage(message: string, privateKeyBase64: string): string {\n const privateKeyBuffer = Buffer.from(privateKeyBase64, \"base64\");\n const signature = sign(null, Buffer.from(message), {\n key: privateKeyBuffer,\n format: \"der\",\n type: \"pkcs8\",\n });\n return signature.toString(\"base64\");\n}\n\n/**\n * Sign an intent for submission to the passkey service\n *\n * @example\n * ```typescript\n * import { signIntent } from \"@rhinestone/1auth/server\";\n *\n * const signedIntent = signIntent(\n * {\n * username: \"alice\",\n * targetChain: 8453,\n * calls: [{ to: \"0x...\", data: \"0x...\", label: \"Buy NFT\" }],\n * },\n * {\n * merchantId: process.env.MERCHANT_ID!,\n * privateKey: process.env.MERCHANT_PRIVATE_KEY!,\n * }\n * );\n * ```\n */\nexport function signIntent(\n params: SignIntentParams,\n config: MerchantConfig\n): SignedIntent {\n const { username, accountAddress, targetChain, calls, tokenRequests } = params;\n const { merchantId, privateKey, expiryMs = 5 * 60 * 1000 } = config;\n\n if (!merchantId || !privateKey) {\n throw new Error(\"Missing merchantId or privateKey in config\");\n }\n\n if (!username && !accountAddress) {\n throw new Error(\"Either username or accountAddress is required\");\n }\n\n if (!targetChain || !calls?.length) {\n throw new Error(\"targetChain and calls are required\");\n }\n\n // Generate nonce and expiry\n const nonce = crypto.randomUUID();\n const expiresAt = Date.now() + expiryMs;\n\n // Create intent data\n const intentData = {\n merchantId,\n targetChain,\n calls,\n username,\n accountAddress,\n nonce,\n expiresAt,\n };\n\n // Create canonical message and sign\n const message = createCanonicalMessage(intentData);\n const signature = signMessage(message, privateKey);\n\n return {\n ...intentData,\n signature,\n tokenRequests,\n };\n}\n\n/**\n * Create a Next.js API route handler for signing intents\n *\n * @example\n * ```typescript\n * // app/api/sign-intent/route.ts\n * import { createSignIntentHandler } from \"@rhinestone/1auth/server\";\n *\n * export const POST = createSignIntentHandler({\n * merchantId: process.env.MERCHANT_ID!,\n * privateKey: process.env.MERCHANT_PRIVATE_KEY!,\n * });\n * ```\n */\nexport function createSignIntentHandler(config: MerchantConfig) {\n return async function handler(request: Request): Promise<Response> {\n // Validate config\n if (!config.merchantId || !config.privateKey) {\n console.error(\"Missing MERCHANT_ID or MERCHANT_PRIVATE_KEY\");\n return Response.json(\n { error: \"Server misconfiguration: missing merchant credentials\" },\n { status: 500 }\n );\n }\n\n try {\n const body = await request.json();\n\n // Validate required fields\n const { targetChain, calls, username, accountAddress, tokenRequests } = body;\n\n if (!targetChain || typeof targetChain !== \"number\") {\n return Response.json(\n { error: \"targetChain is required and must be a number\" },\n { status: 400 }\n );\n }\n\n if (!calls || !Array.isArray(calls) || calls.length === 0) {\n return Response.json(\n { error: \"calls is required and must be a non-empty array\" },\n { status: 400 }\n );\n }\n\n if (!username && !accountAddress) {\n return Response.json(\n { error: \"Either username or accountAddress is required\" },\n { status: 400 }\n );\n }\n\n // Validate each call has a valid address\n for (const call of calls) {\n if (!call.to || !/^0x[a-fA-F0-9]{40}$/.test(call.to)) {\n return Response.json(\n { error: \"Each call must have a valid 'to' address\" },\n { status: 400 }\n );\n }\n }\n\n // Sign the intent\n const signedIntent = signIntent(\n { username, accountAddress, targetChain, calls, tokenRequests },\n config\n );\n\n return Response.json(signedIntent);\n } catch (error) {\n console.error(\"Error signing intent:\", error);\n return Response.json(\n { error: \"Failed to sign intent\" },\n { status: 500 }\n );\n }\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import { sign } from "crypto";
|
|
3
|
+
function createCanonicalMessage(data) {
|
|
4
|
+
return JSON.stringify({
|
|
5
|
+
merchantId: data.merchantId,
|
|
6
|
+
targetChain: data.targetChain,
|
|
7
|
+
calls: data.calls.map((c) => ({
|
|
8
|
+
to: c.to.toLowerCase(),
|
|
9
|
+
data: (c.data || "0x").toLowerCase(),
|
|
10
|
+
value: c.value || "0",
|
|
11
|
+
label: c.label || "",
|
|
12
|
+
sublabel: c.sublabel || ""
|
|
13
|
+
})),
|
|
14
|
+
username: data.username,
|
|
15
|
+
accountAddress: data.accountAddress?.toLowerCase(),
|
|
16
|
+
nonce: data.nonce,
|
|
17
|
+
expiresAt: data.expiresAt
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function signMessage(message, privateKeyBase64) {
|
|
21
|
+
const privateKeyBuffer = Buffer.from(privateKeyBase64, "base64");
|
|
22
|
+
const signature = sign(null, Buffer.from(message), {
|
|
23
|
+
key: privateKeyBuffer,
|
|
24
|
+
format: "der",
|
|
25
|
+
type: "pkcs8"
|
|
26
|
+
});
|
|
27
|
+
return signature.toString("base64");
|
|
28
|
+
}
|
|
29
|
+
function signIntent(params, config) {
|
|
30
|
+
const { username, accountAddress, targetChain, calls, tokenRequests } = params;
|
|
31
|
+
const { merchantId, privateKey, expiryMs = 5 * 60 * 1e3 } = config;
|
|
32
|
+
if (!merchantId || !privateKey) {
|
|
33
|
+
throw new Error("Missing merchantId or privateKey in config");
|
|
34
|
+
}
|
|
35
|
+
if (!username && !accountAddress) {
|
|
36
|
+
throw new Error("Either username or accountAddress is required");
|
|
37
|
+
}
|
|
38
|
+
if (!targetChain || !calls?.length) {
|
|
39
|
+
throw new Error("targetChain and calls are required");
|
|
40
|
+
}
|
|
41
|
+
const nonce = crypto.randomUUID();
|
|
42
|
+
const expiresAt = Date.now() + expiryMs;
|
|
43
|
+
const intentData = {
|
|
44
|
+
merchantId,
|
|
45
|
+
targetChain,
|
|
46
|
+
calls,
|
|
47
|
+
username,
|
|
48
|
+
accountAddress,
|
|
49
|
+
nonce,
|
|
50
|
+
expiresAt
|
|
51
|
+
};
|
|
52
|
+
const message = createCanonicalMessage(intentData);
|
|
53
|
+
const signature = signMessage(message, privateKey);
|
|
54
|
+
return {
|
|
55
|
+
...intentData,
|
|
56
|
+
signature,
|
|
57
|
+
tokenRequests
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function createSignIntentHandler(config) {
|
|
61
|
+
return async function handler(request) {
|
|
62
|
+
if (!config.merchantId || !config.privateKey) {
|
|
63
|
+
console.error("Missing MERCHANT_ID or MERCHANT_PRIVATE_KEY");
|
|
64
|
+
return Response.json(
|
|
65
|
+
{ error: "Server misconfiguration: missing merchant credentials" },
|
|
66
|
+
{ status: 500 }
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const body = await request.json();
|
|
71
|
+
const { targetChain, calls, username, accountAddress, tokenRequests } = body;
|
|
72
|
+
if (!targetChain || typeof targetChain !== "number") {
|
|
73
|
+
return Response.json(
|
|
74
|
+
{ error: "targetChain is required and must be a number" },
|
|
75
|
+
{ status: 400 }
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
if (!calls || !Array.isArray(calls) || calls.length === 0) {
|
|
79
|
+
return Response.json(
|
|
80
|
+
{ error: "calls is required and must be a non-empty array" },
|
|
81
|
+
{ status: 400 }
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (!username && !accountAddress) {
|
|
85
|
+
return Response.json(
|
|
86
|
+
{ error: "Either username or accountAddress is required" },
|
|
87
|
+
{ status: 400 }
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
for (const call of calls) {
|
|
91
|
+
if (!call.to || !/^0x[a-fA-F0-9]{40}$/.test(call.to)) {
|
|
92
|
+
return Response.json(
|
|
93
|
+
{ error: "Each call must have a valid 'to' address" },
|
|
94
|
+
{ status: 400 }
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const signedIntent = signIntent(
|
|
99
|
+
{ username, accountAddress, targetChain, calls, tokenRequests },
|
|
100
|
+
config
|
|
101
|
+
);
|
|
102
|
+
return Response.json(signedIntent);
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error("Error signing intent:", error);
|
|
105
|
+
return Response.json(
|
|
106
|
+
{ error: "Failed to sign intent" },
|
|
107
|
+
{ status: 500 }
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export {
|
|
113
|
+
createSignIntentHandler,
|
|
114
|
+
signIntent
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * Server-side utilities for 1auth SDK\n * Use these in Next.js API routes or server actions\n */\n\nimport { sign } from \"crypto\";\n\nexport interface MerchantConfig {\n /** Merchant ID from registration */\n merchantId: string;\n /** Ed25519 private key (base64 encoded) */\n privateKey: string;\n /** Intent expiry time in ms (default: 5 minutes) */\n expiryMs?: number;\n}\n\nexport interface IntentCall {\n to: string;\n data?: string;\n value?: string;\n label?: string;\n sublabel?: string;\n}\n\nexport interface SignIntentParams {\n username?: string;\n accountAddress?: string;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\nexport interface SignedIntent {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n signature: string;\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\n/**\n * Create canonical message for signing\n * Must match the format expected by passkey service\n */\nfunction createCanonicalMessage(data: {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n}): string {\n return JSON.stringify({\n merchantId: data.merchantId,\n targetChain: data.targetChain,\n calls: data.calls.map((c) => ({\n to: c.to.toLowerCase(),\n data: (c.data || \"0x\").toLowerCase(),\n value: c.value || \"0\",\n label: c.label || \"\",\n sublabel: c.sublabel || \"\",\n })),\n username: data.username,\n accountAddress: data.accountAddress?.toLowerCase(),\n nonce: data.nonce,\n expiresAt: data.expiresAt,\n });\n}\n\n/**\n * Sign an intent with Ed25519 private key\n */\nfunction signMessage(message: string, privateKeyBase64: string): string {\n const privateKeyBuffer = Buffer.from(privateKeyBase64, \"base64\");\n const signature = sign(null, Buffer.from(message), {\n key: privateKeyBuffer,\n format: \"der\",\n type: \"pkcs8\",\n });\n return signature.toString(\"base64\");\n}\n\n/**\n * Sign an intent for submission to the passkey service\n *\n * @example\n * ```typescript\n * import { signIntent } from \"@rhinestone/1auth/server\";\n *\n * const signedIntent = signIntent(\n * {\n * username: \"alice\",\n * targetChain: 8453,\n * calls: [{ to: \"0x...\", data: \"0x...\", label: \"Buy NFT\" }],\n * },\n * {\n * merchantId: process.env.MERCHANT_ID!,\n * privateKey: process.env.MERCHANT_PRIVATE_KEY!,\n * }\n * );\n * ```\n */\nexport function signIntent(\n params: SignIntentParams,\n config: MerchantConfig\n): SignedIntent {\n const { username, accountAddress, targetChain, calls, tokenRequests } = params;\n const { merchantId, privateKey, expiryMs = 5 * 60 * 1000 } = config;\n\n if (!merchantId || !privateKey) {\n throw new Error(\"Missing merchantId or privateKey in config\");\n }\n\n if (!username && !accountAddress) {\n throw new Error(\"Either username or accountAddress is required\");\n }\n\n if (!targetChain || !calls?.length) {\n throw new Error(\"targetChain and calls are required\");\n }\n\n // Generate nonce and expiry\n const nonce = crypto.randomUUID();\n const expiresAt = Date.now() + expiryMs;\n\n // Create intent data\n const intentData = {\n merchantId,\n targetChain,\n calls,\n username,\n accountAddress,\n nonce,\n expiresAt,\n };\n\n // Create canonical message and sign\n const message = createCanonicalMessage(intentData);\n const signature = signMessage(message, privateKey);\n\n return {\n ...intentData,\n signature,\n tokenRequests,\n };\n}\n\n/**\n * Create a Next.js API route handler for signing intents\n *\n * @example\n * ```typescript\n * // app/api/sign-intent/route.ts\n * import { createSignIntentHandler } from \"@rhinestone/1auth/server\";\n *\n * export const POST = createSignIntentHandler({\n * merchantId: process.env.MERCHANT_ID!,\n * privateKey: process.env.MERCHANT_PRIVATE_KEY!,\n * });\n * ```\n */\nexport function createSignIntentHandler(config: MerchantConfig) {\n return async function handler(request: Request): Promise<Response> {\n // Validate config\n if (!config.merchantId || !config.privateKey) {\n console.error(\"Missing MERCHANT_ID or MERCHANT_PRIVATE_KEY\");\n return Response.json(\n { error: \"Server misconfiguration: missing merchant credentials\" },\n { status: 500 }\n );\n }\n\n try {\n const body = await request.json();\n\n // Validate required fields\n const { targetChain, calls, username, accountAddress, tokenRequests } = body;\n\n if (!targetChain || typeof targetChain !== \"number\") {\n return Response.json(\n { error: \"targetChain is required and must be a number\" },\n { status: 400 }\n );\n }\n\n if (!calls || !Array.isArray(calls) || calls.length === 0) {\n return Response.json(\n { error: \"calls is required and must be a non-empty array\" },\n { status: 400 }\n );\n }\n\n if (!username && !accountAddress) {\n return Response.json(\n { error: \"Either username or accountAddress is required\" },\n { status: 400 }\n );\n }\n\n // Validate each call has a valid address\n for (const call of calls) {\n if (!call.to || !/^0x[a-fA-F0-9]{40}$/.test(call.to)) {\n return Response.json(\n { error: \"Each call must have a valid 'to' address\" },\n { status: 400 }\n );\n }\n }\n\n // Sign the intent\n const signedIntent = signIntent(\n { username, accountAddress, targetChain, calls, tokenRequests },\n config\n );\n\n return Response.json(signedIntent);\n } catch (error) {\n console.error(\"Error signing intent:\", error);\n return Response.json(\n { error: \"Failed to sign intent\" },\n { status: 500 }\n );\n }\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/wagmi.d.mts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as _wagmi_core from '@wagmi/core';
|
|
2
|
+
import { P as PasskeyProvider } from './provider-Dgh51NRc.mjs';
|
|
3
|
+
import { P as PasskeyProviderClient } from './client-C1inywuT.mjs';
|
|
4
|
+
|
|
5
|
+
type OneAuthConnectorOptions = {
|
|
6
|
+
client: PasskeyProviderClient;
|
|
7
|
+
chainId?: number;
|
|
8
|
+
storageKey?: string;
|
|
9
|
+
waitForHash?: boolean;
|
|
10
|
+
hashTimeoutMs?: number;
|
|
11
|
+
hashIntervalMs?: number;
|
|
12
|
+
};
|
|
13
|
+
declare function oneAuth(options: OneAuthConnectorOptions): _wagmi_core.CreateConnectorFn<PasskeyProvider, Record<string, unknown>, Record<string, unknown>>;
|
|
14
|
+
|
|
15
|
+
export { type OneAuthConnectorOptions, oneAuth };
|
package/dist/wagmi.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as _wagmi_core from '@wagmi/core';
|
|
2
|
+
import { P as PasskeyProvider } from './provider-q7M728Mn.js';
|
|
3
|
+
import { P as PasskeyProviderClient } from './client-C1inywuT.js';
|
|
4
|
+
|
|
5
|
+
type OneAuthConnectorOptions = {
|
|
6
|
+
client: PasskeyProviderClient;
|
|
7
|
+
chainId?: number;
|
|
8
|
+
storageKey?: string;
|
|
9
|
+
waitForHash?: boolean;
|
|
10
|
+
hashTimeoutMs?: number;
|
|
11
|
+
hashIntervalMs?: number;
|
|
12
|
+
};
|
|
13
|
+
declare function oneAuth(options: OneAuthConnectorOptions): _wagmi_core.CreateConnectorFn<PasskeyProvider, Record<string, unknown>, Record<string, unknown>>;
|
|
14
|
+
|
|
15
|
+
export { type OneAuthConnectorOptions, oneAuth };
|