n8n-nodes-agnicwallet 1.0.4 → 1.0.6
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 +2 -2
- package/dist/credentials/AgnicWalletApi.credentials.d.ts +1 -1
- package/dist/credentials/AgnicWalletApi.credentials.js +17 -17
- package/dist/credentials/AgnicWalletOAuth2Api.credentials.d.ts +1 -1
- package/dist/credentials/AgnicWalletOAuth2Api.credentials.js +51 -51
- package/dist/nodes/X402HttpRequest/X402HttpRequest.node.d.ts +1 -1
- package/dist/nodes/X402HttpRequest/X402HttpRequest.node.js +90 -89
- package/package.json +3 -6
package/README.md
CHANGED
|
@@ -170,7 +170,7 @@ This node requires the AgnicWallet backend API to function. **This is by design
|
|
|
170
170
|
1. You create a free account at [AgnicWallet](https://app.agnicpay.xyz)
|
|
171
171
|
2. You authorize n8n to use your wallet (OAuth2 or API Key)
|
|
172
172
|
3. When making X402 requests, the node calls `api.agnicpay.xyz` to sign payments on your behalf
|
|
173
|
-
4. Your wallet is non-custodial (keys managed
|
|
173
|
+
4. Your wallet is non-custodial (keys managed securely, not stored by AgnicWallet)
|
|
174
174
|
|
|
175
175
|
### Why This Architecture?
|
|
176
176
|
- **No blockchain complexity** - You don't manage private keys or gas fees
|
|
@@ -205,7 +205,7 @@ This is the same architecture used by most n8n community nodes that interact wit
|
|
|
205
205
|
## FAQ
|
|
206
206
|
|
|
207
207
|
### Is my wallet safe?
|
|
208
|
-
Yes! AgnicWallet is non-custodial. Your private keys are managed
|
|
208
|
+
Yes! AgnicWallet is non-custodial. Your private keys are managed securely using industry-standard key management infrastructure, never stored on AgnicWallet servers. The backend only signs transactions you've authorized.
|
|
209
209
|
|
|
210
210
|
### Do I need to trust AgnicWallet?
|
|
211
211
|
Yes, but only as much as you trust Slack, Notion, or Google when using their n8n nodes. You're authorizing AgnicWallet to sign X402 payments on your behalf within your spending limits.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IAuthenticateGeneric, ICredentialType, INodeProperties } from
|
|
1
|
+
import { IAuthenticateGeneric, ICredentialType, INodeProperties } from "n8n-workflow";
|
|
2
2
|
export declare class AgnicWalletApi implements ICredentialType {
|
|
3
3
|
name: string;
|
|
4
4
|
displayName: string;
|
|
@@ -3,37 +3,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AgnicWalletApi = void 0;
|
|
4
4
|
class AgnicWalletApi {
|
|
5
5
|
constructor() {
|
|
6
|
-
this.name =
|
|
7
|
-
this.displayName =
|
|
8
|
-
this.documentationUrl =
|
|
6
|
+
this.name = "agnicWalletApi";
|
|
7
|
+
this.displayName = "AgnicWallet API";
|
|
8
|
+
this.documentationUrl = "https://github.com/agnicpay/n8n-X402-AgnicWallet#setup";
|
|
9
9
|
this.properties = [
|
|
10
10
|
{
|
|
11
|
-
displayName:
|
|
12
|
-
name:
|
|
13
|
-
type:
|
|
14
|
-
default:
|
|
11
|
+
displayName: "User ID",
|
|
12
|
+
name: "userId",
|
|
13
|
+
type: "string",
|
|
14
|
+
default: "",
|
|
15
15
|
required: true,
|
|
16
|
-
description:
|
|
17
|
-
placeholder:
|
|
16
|
+
description: "Your AgnicWallet user ID (from dashboard)",
|
|
17
|
+
placeholder: "user_2kX9mNz8pQw7VbC",
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
displayName:
|
|
21
|
-
name:
|
|
22
|
-
type:
|
|
20
|
+
displayName: "API Token",
|
|
21
|
+
name: "apiToken",
|
|
22
|
+
type: "string",
|
|
23
23
|
typeOptions: {
|
|
24
24
|
password: true,
|
|
25
25
|
},
|
|
26
|
-
default:
|
|
26
|
+
default: "",
|
|
27
27
|
required: true,
|
|
28
|
-
description:
|
|
29
|
-
placeholder:
|
|
28
|
+
description: "Your AgnicWallet API token (starts with agnic_tok_)",
|
|
29
|
+
placeholder: "agnic_tok_sk_live_...",
|
|
30
30
|
},
|
|
31
31
|
];
|
|
32
32
|
this.authenticate = {
|
|
33
|
-
type:
|
|
33
|
+
type: "generic",
|
|
34
34
|
properties: {
|
|
35
35
|
headers: {
|
|
36
|
-
|
|
36
|
+
"X-Agnic-Token": "={{$credentials.apiToken}}",
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
};
|
|
@@ -3,88 +3,88 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AgnicWalletOAuth2Api = void 0;
|
|
4
4
|
class AgnicWalletOAuth2Api {
|
|
5
5
|
constructor() {
|
|
6
|
-
this.name =
|
|
7
|
-
this.extends = [
|
|
8
|
-
this.displayName =
|
|
9
|
-
this.documentationUrl =
|
|
6
|
+
this.name = "agnicWalletOAuth2Api";
|
|
7
|
+
this.extends = ["oAuth2Api"];
|
|
8
|
+
this.displayName = "AgnicWallet OAuth2 API";
|
|
9
|
+
this.documentationUrl = "https://github.com/agnicpay/n8n-X402-AgnicWallet#readme";
|
|
10
10
|
this.properties = [
|
|
11
11
|
{
|
|
12
|
-
displayName:
|
|
13
|
-
name:
|
|
14
|
-
type:
|
|
15
|
-
default:
|
|
12
|
+
displayName: "Grant Type",
|
|
13
|
+
name: "grantType",
|
|
14
|
+
type: "hidden",
|
|
15
|
+
default: "authorizationCode",
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
|
-
displayName:
|
|
19
|
-
name:
|
|
20
|
-
type:
|
|
21
|
-
default:
|
|
18
|
+
displayName: "Authorization URL",
|
|
19
|
+
name: "authUrl",
|
|
20
|
+
type: "string",
|
|
21
|
+
default: "https://api.agnicpay.xyz/oauth/authorize",
|
|
22
22
|
required: true,
|
|
23
|
-
description:
|
|
23
|
+
description: "The OAuth2 authorization endpoint",
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
displayName:
|
|
27
|
-
name:
|
|
28
|
-
type:
|
|
29
|
-
default:
|
|
26
|
+
displayName: "Access Token URL",
|
|
27
|
+
name: "accessTokenUrl",
|
|
28
|
+
type: "string",
|
|
29
|
+
default: "https://api.agnicpay.xyz/oauth/token",
|
|
30
30
|
required: true,
|
|
31
|
-
description:
|
|
31
|
+
description: "The OAuth2 token endpoint",
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
displayName:
|
|
35
|
-
name:
|
|
36
|
-
type:
|
|
37
|
-
default:
|
|
34
|
+
displayName: "Client ID",
|
|
35
|
+
name: "clientId",
|
|
36
|
+
type: "string",
|
|
37
|
+
default: "n8n_default",
|
|
38
38
|
required: true,
|
|
39
|
-
description:
|
|
39
|
+
description: "OAuth2 Client ID (default: n8n_default)",
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
|
-
displayName:
|
|
43
|
-
name:
|
|
44
|
-
type:
|
|
42
|
+
displayName: "Client Secret",
|
|
43
|
+
name: "clientSecret",
|
|
44
|
+
type: "string",
|
|
45
45
|
typeOptions: {
|
|
46
46
|
password: true,
|
|
47
47
|
},
|
|
48
|
-
default:
|
|
49
|
-
description:
|
|
48
|
+
default: "",
|
|
49
|
+
description: "OAuth2 Client Secret (optional for PKCE)",
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
|
-
displayName:
|
|
53
|
-
name:
|
|
54
|
-
type:
|
|
55
|
-
default:
|
|
56
|
-
description:
|
|
52
|
+
displayName: "Scope",
|
|
53
|
+
name: "scope",
|
|
54
|
+
type: "string",
|
|
55
|
+
default: "payments:sign balance:read",
|
|
56
|
+
description: "OAuth2 scopes",
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
|
-
displayName:
|
|
60
|
-
name:
|
|
61
|
-
type:
|
|
62
|
-
default:
|
|
63
|
-
description:
|
|
59
|
+
displayName: "Auth URI Query Parameters",
|
|
60
|
+
name: "authQueryParameters",
|
|
61
|
+
type: "string",
|
|
62
|
+
default: "",
|
|
63
|
+
description: "Additional query parameters for authorization URL",
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
displayName:
|
|
67
|
-
name:
|
|
68
|
-
type:
|
|
66
|
+
displayName: "Authentication",
|
|
67
|
+
name: "authentication",
|
|
68
|
+
type: "options",
|
|
69
69
|
options: [
|
|
70
70
|
{
|
|
71
|
-
name:
|
|
72
|
-
value:
|
|
71
|
+
name: "Body",
|
|
72
|
+
value: "body",
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
|
-
name:
|
|
76
|
-
value:
|
|
75
|
+
name: "Header",
|
|
76
|
+
value: "header",
|
|
77
77
|
},
|
|
78
78
|
],
|
|
79
|
-
default:
|
|
80
|
-
description:
|
|
79
|
+
default: "body",
|
|
80
|
+
description: "How to send credentials",
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
|
-
displayName:
|
|
84
|
-
name:
|
|
85
|
-
type:
|
|
83
|
+
displayName: "Use PKCE",
|
|
84
|
+
name: "usePKCE",
|
|
85
|
+
type: "boolean",
|
|
86
86
|
default: true,
|
|
87
|
-
description:
|
|
87
|
+
description: "Whether to use PKCE (Proof Key for Code Exchange)",
|
|
88
88
|
},
|
|
89
89
|
];
|
|
90
90
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from "n8n-workflow";
|
|
2
2
|
export declare class X402HttpRequest implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
@@ -5,134 +5,134 @@ const n8n_workflow_1 = require("n8n-workflow");
|
|
|
5
5
|
class X402HttpRequest {
|
|
6
6
|
constructor() {
|
|
7
7
|
this.description = {
|
|
8
|
-
displayName:
|
|
9
|
-
name:
|
|
10
|
-
group: [
|
|
8
|
+
displayName: "AgnicWallet X402 Request",
|
|
9
|
+
name: "agnicWalletX402Request",
|
|
10
|
+
group: ["transform"],
|
|
11
11
|
version: 1,
|
|
12
|
-
description:
|
|
12
|
+
description: "Make HTTP requests to X402-enabled APIs with automatic payment via AgnicWallet",
|
|
13
13
|
defaults: {
|
|
14
|
-
name:
|
|
14
|
+
name: "AgnicWallet X402",
|
|
15
15
|
},
|
|
16
16
|
usableAsTool: true,
|
|
17
|
-
inputs: [
|
|
18
|
-
outputs: [
|
|
17
|
+
inputs: ["main"],
|
|
18
|
+
outputs: ["main"],
|
|
19
19
|
credentials: [
|
|
20
20
|
{
|
|
21
|
-
name:
|
|
21
|
+
name: "agnicWalletOAuth2Api",
|
|
22
22
|
required: false,
|
|
23
23
|
displayOptions: {
|
|
24
24
|
show: {
|
|
25
|
-
authentication: [
|
|
25
|
+
authentication: ["oAuth2"],
|
|
26
26
|
},
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
|
-
name:
|
|
30
|
+
name: "agnicWalletApi",
|
|
31
31
|
required: false,
|
|
32
32
|
displayOptions: {
|
|
33
33
|
show: {
|
|
34
|
-
authentication: [
|
|
34
|
+
authentication: ["apiKey"],
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
},
|
|
38
38
|
],
|
|
39
39
|
properties: [
|
|
40
40
|
{
|
|
41
|
-
displayName:
|
|
42
|
-
name:
|
|
43
|
-
type:
|
|
41
|
+
displayName: "Authentication",
|
|
42
|
+
name: "authentication",
|
|
43
|
+
type: "options",
|
|
44
44
|
options: [
|
|
45
45
|
{
|
|
46
|
-
name:
|
|
47
|
-
value:
|
|
48
|
-
description:
|
|
46
|
+
name: "OAuth2",
|
|
47
|
+
value: "oAuth2",
|
|
48
|
+
description: "Recommended: Connect your account",
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
|
-
name:
|
|
52
|
-
value:
|
|
53
|
-
description:
|
|
51
|
+
name: "API Key",
|
|
52
|
+
value: "apiKey",
|
|
53
|
+
description: "For CI/CD or programmatic access",
|
|
54
54
|
},
|
|
55
55
|
],
|
|
56
|
-
default:
|
|
57
|
-
description:
|
|
56
|
+
default: "oAuth2",
|
|
57
|
+
description: "How to authenticate with AgnicWallet",
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
|
-
displayName:
|
|
61
|
-
name:
|
|
62
|
-
type:
|
|
60
|
+
displayName: "Method",
|
|
61
|
+
name: "method",
|
|
62
|
+
type: "options",
|
|
63
63
|
options: [
|
|
64
64
|
{
|
|
65
|
-
name:
|
|
66
|
-
value:
|
|
65
|
+
name: "GET",
|
|
66
|
+
value: "GET",
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
|
-
name:
|
|
70
|
-
value:
|
|
69
|
+
name: "POST",
|
|
70
|
+
value: "POST",
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
|
-
name:
|
|
74
|
-
value:
|
|
73
|
+
name: "PUT",
|
|
74
|
+
value: "PUT",
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
|
-
name:
|
|
78
|
-
value:
|
|
77
|
+
name: "DELETE",
|
|
78
|
+
value: "DELETE",
|
|
79
79
|
},
|
|
80
80
|
],
|
|
81
|
-
default:
|
|
82
|
-
description:
|
|
81
|
+
default: "GET",
|
|
82
|
+
description: "The HTTP method to use",
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
|
-
displayName:
|
|
86
|
-
name:
|
|
87
|
-
type:
|
|
88
|
-
default:
|
|
85
|
+
displayName: "URL",
|
|
86
|
+
name: "url",
|
|
87
|
+
type: "string",
|
|
88
|
+
default: "",
|
|
89
89
|
required: true,
|
|
90
|
-
placeholder:
|
|
91
|
-
description:
|
|
90
|
+
placeholder: "https://api.example.com/endpoint",
|
|
91
|
+
description: "The URL of the X402-enabled API",
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
|
-
displayName:
|
|
95
|
-
name:
|
|
96
|
-
type:
|
|
94
|
+
displayName: "Headers",
|
|
95
|
+
name: "headers",
|
|
96
|
+
type: "fixedCollection",
|
|
97
97
|
typeOptions: {
|
|
98
98
|
multipleValues: true,
|
|
99
99
|
},
|
|
100
100
|
default: {},
|
|
101
101
|
options: [
|
|
102
102
|
{
|
|
103
|
-
name:
|
|
104
|
-
displayName:
|
|
103
|
+
name: "header",
|
|
104
|
+
displayName: "Header",
|
|
105
105
|
values: [
|
|
106
106
|
{
|
|
107
|
-
displayName:
|
|
108
|
-
name:
|
|
109
|
-
type:
|
|
110
|
-
default:
|
|
111
|
-
description:
|
|
107
|
+
displayName: "Name",
|
|
108
|
+
name: "name",
|
|
109
|
+
type: "string",
|
|
110
|
+
default: "",
|
|
111
|
+
description: "Name of the header",
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
|
-
displayName:
|
|
115
|
-
name:
|
|
116
|
-
type:
|
|
117
|
-
default:
|
|
118
|
-
description:
|
|
114
|
+
displayName: "Value",
|
|
115
|
+
name: "value",
|
|
116
|
+
type: "string",
|
|
117
|
+
default: "",
|
|
118
|
+
description: "Value of the header",
|
|
119
119
|
},
|
|
120
120
|
],
|
|
121
121
|
},
|
|
122
122
|
],
|
|
123
|
-
description:
|
|
123
|
+
description: "Additional headers to send with the request",
|
|
124
124
|
},
|
|
125
125
|
{
|
|
126
|
-
displayName:
|
|
127
|
-
name:
|
|
128
|
-
type:
|
|
129
|
-
default:
|
|
126
|
+
displayName: "Body",
|
|
127
|
+
name: "body",
|
|
128
|
+
type: "json",
|
|
129
|
+
default: "{}",
|
|
130
130
|
displayOptions: {
|
|
131
131
|
show: {
|
|
132
|
-
method: [
|
|
132
|
+
method: ["POST", "PUT"],
|
|
133
133
|
},
|
|
134
134
|
},
|
|
135
|
-
description:
|
|
135
|
+
description: "JSON body to send with the request",
|
|
136
136
|
},
|
|
137
137
|
],
|
|
138
138
|
};
|
|
@@ -143,31 +143,30 @@ class X402HttpRequest {
|
|
|
143
143
|
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
144
144
|
try {
|
|
145
145
|
// Get authentication type
|
|
146
|
-
const authentication = this.getNodeParameter(
|
|
146
|
+
const authentication = this.getNodeParameter("authentication", itemIndex);
|
|
147
147
|
let apiBaseUrl;
|
|
148
148
|
let authHeader;
|
|
149
|
-
// Use AgnicWallet backend API endpoint (production cloud
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (authentication === 'oAuth2') {
|
|
149
|
+
// Use AgnicWallet backend API endpoint (production cloud)
|
|
150
|
+
apiBaseUrl = "https://api.agnicpay.xyz";
|
|
151
|
+
if (authentication === "oAuth2") {
|
|
153
152
|
// OAuth2 authentication
|
|
154
|
-
const credentials = await this.getCredentials(
|
|
153
|
+
const credentials = (await this.getCredentials("agnicWalletOAuth2Api", itemIndex));
|
|
155
154
|
authHeader = `Bearer ${credentials.oauthTokenData.access_token}`;
|
|
156
155
|
}
|
|
157
156
|
else {
|
|
158
157
|
// API Key authentication
|
|
159
|
-
const credentials = await this.getCredentials(
|
|
158
|
+
const credentials = await this.getCredentials("agnicWalletApi", itemIndex);
|
|
160
159
|
const { apiToken } = credentials;
|
|
161
160
|
authHeader = apiToken;
|
|
162
161
|
}
|
|
163
162
|
// Get parameters
|
|
164
|
-
const method = this.getNodeParameter(
|
|
165
|
-
const url = this.getNodeParameter(
|
|
166
|
-
const headersConfig = this.getNodeParameter(
|
|
167
|
-
const body = this.getNodeParameter(
|
|
163
|
+
const method = this.getNodeParameter("method", itemIndex);
|
|
164
|
+
const url = this.getNodeParameter("url", itemIndex);
|
|
165
|
+
const headersConfig = this.getNodeParameter("headers", itemIndex, {});
|
|
166
|
+
const body = this.getNodeParameter("body", itemIndex, "{}");
|
|
168
167
|
// Build headers
|
|
169
168
|
const headers = {
|
|
170
|
-
|
|
169
|
+
"Content-Type": "application/json",
|
|
171
170
|
};
|
|
172
171
|
if (headersConfig.header) {
|
|
173
172
|
headersConfig.header.forEach((h) => {
|
|
@@ -179,10 +178,12 @@ class X402HttpRequest {
|
|
|
179
178
|
url,
|
|
180
179
|
method,
|
|
181
180
|
headers,
|
|
182
|
-
body: method ===
|
|
181
|
+
body: method === "POST" || method === "PUT"
|
|
182
|
+
? JSON.parse(body)
|
|
183
|
+
: undefined,
|
|
183
184
|
agnicWalletApi: apiBaseUrl,
|
|
184
185
|
authHeader,
|
|
185
|
-
isOAuth: authentication ===
|
|
186
|
+
isOAuth: authentication === "oAuth2",
|
|
186
187
|
});
|
|
187
188
|
returnData.push({
|
|
188
189
|
json: response,
|
|
@@ -192,7 +193,7 @@ class X402HttpRequest {
|
|
|
192
193
|
});
|
|
193
194
|
}
|
|
194
195
|
catch (error) {
|
|
195
|
-
const errorMessage = error instanceof Error ? error.message :
|
|
196
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
196
197
|
if (this.continueOnFail()) {
|
|
197
198
|
returnData.push({
|
|
198
199
|
json: {
|
|
@@ -227,7 +228,7 @@ async function makeX402Request(context, config) {
|
|
|
227
228
|
context.logger.info(`Response status: ${response.status}`);
|
|
228
229
|
// 2. If 402 Payment Required, use AgnicWallet to sign
|
|
229
230
|
if (response.status === 402) {
|
|
230
|
-
context.logger.info(
|
|
231
|
+
context.logger.info("402 Payment Required detected, parsing payment requirements...");
|
|
231
232
|
// Get response text first for debugging
|
|
232
233
|
const responseText = await response.text();
|
|
233
234
|
context.logger.info(`Payment requirements response: ${responseText}`);
|
|
@@ -236,25 +237,25 @@ async function makeX402Request(context, config) {
|
|
|
236
237
|
paymentRequirements = JSON.parse(responseText);
|
|
237
238
|
}
|
|
238
239
|
catch (parseError) {
|
|
239
|
-
throw new Error(`Failed to parse payment requirements: ${parseError instanceof Error ? parseError.message :
|
|
240
|
+
throw new Error(`Failed to parse payment requirements: ${parseError instanceof Error ? parseError.message : "Unknown error"}. Response: ${responseText}`);
|
|
240
241
|
}
|
|
241
242
|
context.logger.info(`Payment required: ${JSON.stringify(paymentRequirements)}`);
|
|
242
243
|
// 3. Call AgnicWallet signing API
|
|
243
244
|
context.logger.info(`Calling AgnicWallet API at: ${agnicWalletApi}/api/sign-payment`);
|
|
244
245
|
// Build auth headers based on auth type
|
|
245
246
|
const authHeaders = {
|
|
246
|
-
|
|
247
|
+
"Content-Type": "application/json",
|
|
247
248
|
};
|
|
248
249
|
if (isOAuth) {
|
|
249
250
|
// OAuth: Use Authorization header with Bearer token
|
|
250
|
-
authHeaders[
|
|
251
|
+
authHeaders["Authorization"] = authHeader;
|
|
251
252
|
}
|
|
252
253
|
else {
|
|
253
254
|
// API Key: Use X-Agnic-Token header
|
|
254
|
-
authHeaders[
|
|
255
|
+
authHeaders["X-Agnic-Token"] = authHeader;
|
|
255
256
|
}
|
|
256
257
|
const signingResponse = await fetch(`${agnicWalletApi}/api/sign-payment`, {
|
|
257
|
-
method:
|
|
258
|
+
method: "POST",
|
|
258
259
|
headers: authHeaders,
|
|
259
260
|
body: JSON.stringify({
|
|
260
261
|
paymentRequirements,
|
|
@@ -266,18 +267,18 @@ async function makeX402Request(context, config) {
|
|
|
266
267
|
context.logger.error(`AgnicWallet signing failed: ${errorText}`);
|
|
267
268
|
throw new Error(`Payment signing failed (${signingResponse.status}): ${errorText}`);
|
|
268
269
|
}
|
|
269
|
-
const signingResult = await signingResponse.json();
|
|
270
|
+
const signingResult = (await signingResponse.json());
|
|
270
271
|
const { paymentHeader, amountPaid } = signingResult;
|
|
271
272
|
context.logger.info(`Payment signed successfully: $${amountPaid}`);
|
|
272
273
|
context.logger.info(`Payment header (Base64): ${paymentHeader}`);
|
|
273
274
|
// 4. Retry original request with payment header
|
|
274
275
|
// The paymentHeader is already Base64-encoded and X402-compliant
|
|
275
|
-
context.logger.info(
|
|
276
|
+
context.logger.info("Retrying request with X402 payment header...");
|
|
276
277
|
response = await fetch(url, {
|
|
277
278
|
method,
|
|
278
279
|
headers: {
|
|
279
280
|
...headers,
|
|
280
|
-
|
|
281
|
+
"X-PAYMENT": paymentHeader,
|
|
281
282
|
},
|
|
282
283
|
body: body ? JSON.stringify(body) : undefined,
|
|
283
284
|
});
|
|
@@ -296,7 +297,7 @@ async function makeX402Request(context, config) {
|
|
|
296
297
|
result = { data: resultText };
|
|
297
298
|
}
|
|
298
299
|
return {
|
|
299
|
-
...(typeof result ===
|
|
300
|
+
...(typeof result === "object" && result !== null ? result : {}),
|
|
300
301
|
_agnicWallet: {
|
|
301
302
|
paymentMade: true,
|
|
302
303
|
amountPaid,
|
|
@@ -319,7 +320,7 @@ async function makeX402Request(context, config) {
|
|
|
319
320
|
}
|
|
320
321
|
}
|
|
321
322
|
catch (error) {
|
|
322
|
-
context.logger.error(`Error in makeX402Request: ${error instanceof Error ? error.message :
|
|
323
|
+
context.logger.error(`Error in makeX402Request: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
323
324
|
throw error;
|
|
324
325
|
}
|
|
325
326
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-agnicwallet",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "n8n community node for AgnicWallet - automated Web3 payments for X402 APIs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|
|
@@ -35,10 +35,8 @@
|
|
|
35
35
|
"build": "tsc && gulp build:icons",
|
|
36
36
|
"dev": "tsc --watch",
|
|
37
37
|
"format": "prettier nodes credentials --write",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"prepublishOnly": "npm run build",
|
|
41
|
-
"test": "jest"
|
|
38
|
+
"format:check": "prettier nodes credentials --check",
|
|
39
|
+
"prepublishOnly": "npm run build"
|
|
42
40
|
},
|
|
43
41
|
"files": [
|
|
44
42
|
"dist"
|
|
@@ -61,7 +59,6 @@
|
|
|
61
59
|
"gulp": "^4.0.2",
|
|
62
60
|
"n8n-workflow": "^1.40.0",
|
|
63
61
|
"prettier": "^3.1.0",
|
|
64
|
-
"tslint": "^5.20.1",
|
|
65
62
|
"typescript": "^5.3.0"
|
|
66
63
|
},
|
|
67
64
|
"peerDependencies": {
|