@atxp/client 0.2.5 → 0.2.7

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.
Files changed (38) hide show
  1. package/package.json +3 -3
  2. package/dist/src/atxpClient.d.ts +0 -14
  3. package/dist/src/atxpClient.d.ts.map +0 -1
  4. package/dist/src/atxpClient.js +0 -62
  5. package/dist/src/atxpClient.js.map +0 -1
  6. package/dist/src/atxpFetcher.d.ts +0 -71
  7. package/dist/src/atxpFetcher.d.ts.map +0 -1
  8. package/dist/src/atxpFetcher.js +0 -347
  9. package/dist/src/atxpFetcher.js.map +0 -1
  10. package/dist/src/clientTestHelpers.d.ts +0 -6
  11. package/dist/src/clientTestHelpers.d.ts.map +0 -1
  12. package/dist/src/clientTestHelpers.js +0 -94
  13. package/dist/src/clientTestHelpers.js.map +0 -1
  14. package/dist/src/index.d.ts +0 -7
  15. package/dist/src/index.d.ts.map +0 -1
  16. package/dist/src/index.js +0 -7
  17. package/dist/src/index.js.map +0 -1
  18. package/dist/src/oAuth.d.ts +0 -44
  19. package/dist/src/oAuth.d.ts.map +0 -1
  20. package/dist/src/oAuth.js +0 -274
  21. package/dist/src/oAuth.js.map +0 -1
  22. package/dist/src/setup.expo.d.ts +0 -2
  23. package/dist/src/setup.expo.d.ts.map +0 -1
  24. package/dist/src/setup.expo.js +0 -42
  25. package/dist/src/setup.expo.js.map +0 -1
  26. package/dist/src/solanaAccount.d.ts +0 -9
  27. package/dist/src/solanaAccount.d.ts.map +0 -1
  28. package/dist/src/solanaAccount.js +0 -19
  29. package/dist/src/solanaAccount.js.map +0 -1
  30. package/dist/src/solanaPaymentMaker.d.ts +0 -17
  31. package/dist/src/solanaPaymentMaker.d.ts.map +0 -1
  32. package/dist/src/solanaPaymentMaker.js +0 -62
  33. package/dist/src/solanaPaymentMaker.js.map +0 -1
  34. package/dist/src/types.d.ts +0 -58
  35. package/dist/src/types.d.ts.map +0 -1
  36. package/dist/src/types.js +0 -2
  37. package/dist/src/types.js.map +0 -1
  38. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,94 +0,0 @@
1
- import { DEFAULT_AUTHORIZATION_SERVER } from '@longrun/atxp-common';
2
- export function mockResourceServer(mock, baseUrl = 'https://example.com', resourcePath = '/mcp', authServerUrl = DEFAULT_AUTHORIZATION_SERVER) {
3
- mock.route({
4
- name: `${baseUrl}/.well-known/oauth-protected-resource${resourcePath}`,
5
- url: `${baseUrl}/.well-known/oauth-protected-resource${resourcePath}`,
6
- response: {
7
- body: {
8
- resource: baseUrl + resourcePath,
9
- authorization_servers: [authServerUrl]
10
- }
11
- }
12
- });
13
- mock.route({
14
- name: `GET ${baseUrl}${resourcePath}`,
15
- url: `${baseUrl}${resourcePath}`,
16
- method: 'get',
17
- response: {
18
- // Indicate that SSE is not supported - clients can only POST to this MCP server
19
- status: 405
20
- }
21
- });
22
- return mock;
23
- }
24
- export function mockAuthorizationServer(mock, baseUrl = DEFAULT_AUTHORIZATION_SERVER, paymentRequests = {}) {
25
- mock.get(`${baseUrl}/.well-known/oauth-authorization-server`, {
26
- issuer: `${baseUrl}`,
27
- authorization_endpoint: `${baseUrl}/authorize`,
28
- registration_endpoint: `${baseUrl}/register`,
29
- token_endpoint: `${baseUrl}/token`,
30
- introspection_endpoint: `${baseUrl}/introspect`
31
- });
32
- // Use the more verbose route method to name the route, so we can .modifyRoute it later
33
- mock.route({
34
- name: `${baseUrl}/token`,
35
- url: `${baseUrl}/token`,
36
- method: 'post',
37
- repeat: 1,
38
- response: {
39
- access_token: 'testAccessToken',
40
- refresh_token: 'testRefreshToken',
41
- token_type: 'Bearer',
42
- expires_in: 3600
43
- }
44
- });
45
- mock.route({
46
- name: `${baseUrl}/register`,
47
- url: `${baseUrl}/register`,
48
- method: 'post',
49
- response: {
50
- status: 201,
51
- body: {
52
- client_id: 'testClientId',
53
- client_secret: 'testClientSecret',
54
- client_secret_expires_at: Date.now() + 1000 * 60 * 60 * 24 * 30
55
- }
56
- }
57
- });
58
- mock.route({
59
- name: `${baseUrl}/introspect`,
60
- url: `${baseUrl}/introspect`,
61
- method: 'post',
62
- repeat: 1,
63
- response: {
64
- active: true,
65
- client_id: 'testClientId',
66
- username: 'testUsername',
67
- sub: 'testUser'
68
- }
69
- });
70
- for (const [paymentRequestId, amount] of Object.entries(paymentRequests)) {
71
- mock.route({
72
- name: `get ${baseUrl}/payment-request/${paymentRequestId}`,
73
- url: `${baseUrl}/payment-request/${paymentRequestId}`,
74
- method: 'get',
75
- response: {
76
- amount,
77
- currency: 'USDC',
78
- network: 'solana',
79
- destination: 'testDestination',
80
- resourceName: 'testResourceName'
81
- }
82
- });
83
- mock.route({
84
- name: `put ${baseUrl}/payment-request/${paymentRequestId}`,
85
- url: `${baseUrl}/payment-request/${paymentRequestId}`,
86
- method: 'put',
87
- response: {
88
- status: 200
89
- }
90
- });
91
- }
92
- return mock;
93
- }
94
- //# sourceMappingURL=clientTestHelpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"clientTestHelpers.js","sourceRoot":"","sources":["../../src/clientTestHelpers.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- export * from './atxpClient.js';
2
- export * from './oAuth.js';
3
- export * from './atxpFetcher.js';
4
- export * from './solanaPaymentMaker.js';
5
- export * from './solanaAccount.js';
6
- export * from './types.js';
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAC"}
package/dist/src/index.js DELETED
@@ -1,7 +0,0 @@
1
- export * from './atxpClient.js';
2
- export * from './oAuth.js';
3
- export * from './atxpFetcher.js';
4
- export * from './solanaPaymentMaker.js';
5
- export * from './solanaAccount.js';
6
- export * from './types.js';
7
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAC"}
@@ -1,44 +0,0 @@
1
- import * as oauth from 'oauth4webapi';
2
- import { OAuthResourceClient } from '@longrun/atxp-common';
3
- import { AccessToken, ClientCredentials, FetchLike, Logger, OAuthDb, PKCEValues } from '@longrun/atxp-common';
4
- export declare class OAuthAuthenticationRequiredError extends Error {
5
- readonly url: string;
6
- readonly resourceServerUrl: string;
7
- readonly idempotencyKey: string;
8
- constructor(url: string, resourceServerUrl: string, idempotencyKey: string);
9
- static create(url: string, resourceServerUrl: string, token?: string): Promise<OAuthAuthenticationRequiredError>;
10
- }
11
- export interface OAuthClientConfig {
12
- userId: string;
13
- db: OAuthDb;
14
- callbackUrl: string;
15
- isPublic: boolean;
16
- fetchFn?: FetchLike;
17
- sideChannelFetch?: FetchLike;
18
- strict?: boolean;
19
- allowInsecureRequests?: boolean;
20
- clientName?: string;
21
- logger?: Logger;
22
- }
23
- export declare class OAuthClient extends OAuthResourceClient {
24
- protected db: OAuthDb;
25
- protected userId: string;
26
- protected fetchFn: FetchLike;
27
- constructor({ userId, db, callbackUrl, clientName, isPublic, fetchFn, sideChannelFetch, strict, allowInsecureRequests, logger }: OAuthClientConfig);
28
- protected extractResourceUrl: (response: Response) => string | null;
29
- fetch: FetchLike;
30
- makeAuthorizationUrl: (url: string, resourceUrl: string) => Promise<URL>;
31
- handleCallback: (url: string) => Promise<void>;
32
- getRegistrationMetadata: () => Promise<Partial<oauth.OmitSymbolProperties<oauth.Client>>>;
33
- protected generatePKCE: (url: string, resourceUrl: string) => Promise<{
34
- codeVerifier: string;
35
- codeChallenge: string;
36
- state: string;
37
- }>;
38
- protected makeTokenRequestAndClient: (authorizationServer: oauth.AuthorizationServer, credentials: ClientCredentials, codeVerifier: string, authResponse: URLSearchParams) => Promise<[Response, oauth.Client]>;
39
- protected exchangeCodeForToken: (authResponse: URLSearchParams, pkceValues: PKCEValues, authorizationServer: oauth.AuthorizationServer) => Promise<string>;
40
- protected getAccessToken: (url: string) => Promise<AccessToken | null>;
41
- protected tryRefreshToken: (url: string) => Promise<AccessToken | null>;
42
- protected _doFetch: FetchLike;
43
- }
44
- //# sourceMappingURL=oAuth.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oAuth.d.ts","sourceRoot":"","sources":["../../src/oAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAG9G,qBAAa,gCAAiC,SAAQ,KAAK;aAEvC,GAAG,EAAE,MAAM;aACX,iBAAiB,EAAE,MAAM;aAGzB,cAAc,EAAE,MAAM;gBAJtB,GAAG,EAAE,MAAM,EACX,iBAAiB,EAAE,MAAM,EAGzB,cAAc,EAAE,MAAM;WAO3B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gCAAgC,CAAC;CAOvH;AAgBD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,WAAY,SAAQ,mBAAmB;IAClD,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC;gBAEjB,EACV,MAAM,EACN,EAAE,EACF,WAAW,EACX,UAAwB,EACxB,QAAQ,EACR,OAAe,EACf,gBAA0B,EAC1B,MAAc,EACd,qBAA8D,EAC9D,MAA4B,EAC7B,EAAE,iBAAiB;IAgBpB,SAAS,CAAC,kBAAkB,GAAI,UAAU,QAAQ,KAAG,MAAM,GAAG,IAAI,CAgBjE;IAED,KAAK,EAAE,SAAS,CAoCf;IAED,oBAAoB,GAAU,KAAK,MAAM,EAAE,aAAa,MAAM,KAAG,OAAO,CAAC,GAAG,CAAC,CAa5E;IAED,cAAc,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAsClD;IAEQ,uBAAuB,QAAa,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAqBtG;IAED,SAAS,CAAC,YAAY,GAAU,KAAK,MAAM,EAAE,aAAa,MAAM,KAAG,OAAO,CAAC;QACzE,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAsBD;IAED,SAAS,CAAC,yBAAyB,GACjC,qBAAqB,KAAK,CAAC,mBAAmB,EAC9C,aAAa,iBAAiB,EAC9B,cAAc,MAAM,EACpB,cAAc,eAAe,KAC5B,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAkBnC;IAED,SAAS,CAAC,oBAAoB,GAC5B,cAAc,eAAe,EAC7B,YAAY,UAAU,EACtB,qBAAqB,KAAK,CAAC,mBAAmB,KAC7C,OAAO,CAAC,MAAM,CAAC,CA6BjB;IAED,SAAS,CAAC,cAAc,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAW1E;IAED,SAAS,CAAC,eAAe,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAqC3E;IAED,SAAS,CAAC,QAAQ,EAAE,SAAS,CAsB5B;CACF"}
package/dist/src/oAuth.js DELETED
@@ -1,274 +0,0 @@
1
- import * as oauth from 'oauth4webapi';
2
- import { OAuthResourceClient } from '@longrun/atxp-common';
3
- import { crypto } from '@longrun/atxp-common';
4
- import { ConsoleLogger } from '@longrun/atxp-common';
5
- export class OAuthAuthenticationRequiredError extends Error {
6
- constructor(url, resourceServerUrl,
7
- // TODO: Remove OAuthError idempotencyKey - these errors shouldn't need to be
8
- // de-duplicated anymore.
9
- idempotencyKey) {
10
- super(`OAuth authentication required. Resource server url: ${resourceServerUrl}`);
11
- this.url = url;
12
- this.resourceServerUrl = resourceServerUrl;
13
- this.idempotencyKey = idempotencyKey;
14
- this.name = 'OAuthAuthenticationRequiredError';
15
- this.idempotencyKey = idempotencyKey;
16
- }
17
- static async create(url, resourceServerUrl, token) {
18
- const baseUrl = OAuthClient.trimToPath(url);
19
- const source = `${baseUrl}|${resourceServerUrl}|${token}`;
20
- const hash = await crypto.digest(new TextEncoder().encode(source));
21
- const idempotencyKey = crypto.toHex(hash);
22
- return new OAuthAuthenticationRequiredError(url, resourceServerUrl, idempotencyKey);
23
- }
24
- }
25
- const CHUNK_SIZE = 0x8000;
26
- function encodeBase64Url(input) {
27
- if (input instanceof ArrayBuffer) {
28
- input = new Uint8Array(input);
29
- }
30
- const arr = [];
31
- for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {
32
- // @ts-expect-error - subarray is not defined on ArrayBuffer
33
- arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
34
- }
35
- return btoa(arr.join('')).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
36
- }
37
- export class OAuthClient extends OAuthResourceClient {
38
- constructor({ userId, db, callbackUrl, clientName = callbackUrl, isPublic, fetchFn = fetch, sideChannelFetch = fetchFn, strict = false, allowInsecureRequests = process.env.NODE_ENV === 'development', logger = new ConsoleLogger() }) {
39
- super({
40
- db: db,
41
- callbackUrl,
42
- isPublic,
43
- sideChannelFetch,
44
- strict,
45
- allowInsecureRequests,
46
- clientName,
47
- logger
48
- });
49
- this.extractResourceUrl = (response) => {
50
- if (response.status !== 401) {
51
- return null;
52
- }
53
- const header = response.headers.get('www-authenticate') || '';
54
- const match = header.match(/^Bearer resource_metadata="([^"]+)"$/);
55
- if (match) {
56
- return this.normalizeResourceServerUrl(match[1]);
57
- }
58
- // handle 'www-authenticate: https://mymcp.com/mcp'
59
- // This is NOT a valid www-authenticate header, and also doesn't conform with the updated 2025-06-18 version of
60
- // the MCP spec. However, it is what we were originally using for proxying requests, so we still support it.
61
- if (header.match(/^https?:\/\//)) {
62
- return this.normalizeResourceServerUrl(header);
63
- }
64
- return null;
65
- };
66
- this.fetch = async (url, init) => {
67
- let response = await this._doFetch(url, init);
68
- if (response.status === 401) {
69
- this.logger.info('Received 401 Unauthorized status');
70
- let resourceUrl = this.extractResourceUrl(response);
71
- const calledUrl = OAuthClient.trimToPath(url instanceof URL ? url.toString() : url);
72
- // If the response indicates an expired token, try to refresh it
73
- if (response.headers.get('www-authenticate')?.includes('error="invalid_grant"')) {
74
- this.logger.info(`Response includes invalid_grant error, attempting to refresh token for ${resourceUrl}`);
75
- let refreshUrl = resourceUrl;
76
- if (!refreshUrl) {
77
- this.logger.info(`Refresh: No resource url found in response www-authenticate header, falling back to the called url ${calledUrl} (this could be incorrect if the called server is just proxying back an oauth failure)`);
78
- refreshUrl = calledUrl;
79
- }
80
- const newToken = await this.tryRefreshToken(refreshUrl);
81
- if (newToken) {
82
- response = await this._doFetch(url, init);
83
- resourceUrl = this.extractResourceUrl(response);
84
- }
85
- }
86
- if (response.status === 401) /* still */ {
87
- // If we couldn't get a valid resourceServerUrl from wwwAuthenticate, use the original URL
88
- if (!resourceUrl) {
89
- this.logger.info(`No resource url found in response www-authenticate header, falling back to the called url ${calledUrl} (this could be incorrect if the called server is just proxying back an oauth failure)`);
90
- resourceUrl = calledUrl;
91
- }
92
- const token = await this.getAccessToken(calledUrl);
93
- this.logger.info(`Throwing OAuthAuthenticationRequiredError for ${calledUrl}, resource: ${resourceUrl}`);
94
- throw await OAuthAuthenticationRequiredError.create(calledUrl, resourceUrl, token?.accessToken);
95
- }
96
- }
97
- return response;
98
- };
99
- this.makeAuthorizationUrl = async (url, resourceUrl) => {
100
- resourceUrl = this.normalizeResourceServerUrl(resourceUrl);
101
- const authorizationServer = await this.getAuthorizationServer(resourceUrl);
102
- const credentials = await this.getClientCredentials(authorizationServer);
103
- const pkceValues = await this.generatePKCE(url, resourceUrl);
104
- const authorizationUrl = new URL(authorizationServer.authorization_endpoint || '');
105
- authorizationUrl.searchParams.set('client_id', credentials.clientId);
106
- authorizationUrl.searchParams.set('redirect_uri', credentials.redirectUri);
107
- authorizationUrl.searchParams.set('response_type', 'code');
108
- authorizationUrl.searchParams.set('code_challenge', pkceValues.codeChallenge);
109
- authorizationUrl.searchParams.set('code_challenge_method', 'S256');
110
- authorizationUrl.searchParams.set('state', pkceValues.state);
111
- return authorizationUrl;
112
- };
113
- this.handleCallback = async (url) => {
114
- this.logger.info(`Handling authorization code callback: ${url}`);
115
- const callbackUrl = new URL(url);
116
- const state = callbackUrl.searchParams.get('state');
117
- if (!state) {
118
- throw new Error('No state parameter found in callback URL');
119
- }
120
- // Get the PKCE values and resource server URL from the database using the state
121
- const pkceValues = await this.db.getPKCEValues(this.userId, state);
122
- if (!pkceValues) {
123
- throw new Error(`No PKCE values found for state: ${state}`);
124
- }
125
- // Get the authorization server configuration
126
- const authorizationServer = await this.getAuthorizationServer(pkceValues.resourceUrl);
127
- // Get the client credentials
128
- const credentials = await this.getClientCredentials(authorizationServer);
129
- // Create the client configuration
130
- const client = {
131
- client_id: credentials.clientId,
132
- token_endpoint_auth_method: 'client_secret_post'
133
- };
134
- // Validate the authorization response
135
- const authResponse = await oauth.validateAuthResponse(authorizationServer, client, callbackUrl, state);
136
- // Exchange the code for tokens
137
- await this.exchangeCodeForToken(authResponse, pkceValues, authorizationServer);
138
- };
139
- this.getRegistrationMetadata = async () => {
140
- const grantTypes = ['authorization_code', 'refresh_token'];
141
- if (!this.isPublic) {
142
- grantTypes.push('client_credentials');
143
- }
144
- let tokenEndpointAuthMethod = 'none';
145
- if (!this.isPublic) {
146
- tokenEndpointAuthMethod = 'client_secret_post';
147
- }
148
- // Create client metadata for registration
149
- const clientMetadata = {
150
- // Required fields for public client
151
- redirect_uris: [this.callbackUrl],
152
- response_types: ['code'],
153
- grant_types: grantTypes,
154
- token_endpoint_auth_method: tokenEndpointAuthMethod,
155
- client_name: `OAuth Client for ${this.callbackUrl}`,
156
- };
157
- return clientMetadata;
158
- };
159
- this.generatePKCE = async (url, resourceUrl) => {
160
- resourceUrl = this.normalizeResourceServerUrl(resourceUrl);
161
- // Generate a random code verifier
162
- const codeVerifier = oauth.generateRandomCodeVerifier();
163
- // Calculate the code challenge
164
- // Use our platform-agnostic crypto implementation
165
- const codeChallenge = encodeBase64Url(await crypto.digest(new TextEncoder().encode(codeVerifier)));
166
- // Generate a random state
167
- const state = oauth.generateRandomState();
168
- // Save the PKCE values in the database
169
- await this.db.savePKCEValues(this.userId, state, {
170
- url,
171
- codeVerifier,
172
- codeChallenge: codeChallenge,
173
- resourceUrl
174
- });
175
- return { codeVerifier, codeChallenge: codeChallenge, state };
176
- };
177
- this.makeTokenRequestAndClient = async (authorizationServer, credentials, codeVerifier, authResponse) => {
178
- const [client, clientAuth] = this.makeOAuthClientAndAuth(credentials);
179
- const options = {
180
- [oauth.customFetch]: this.sideChannelFetch,
181
- [oauth.allowInsecureRequests]: this.allowInsecureRequests
182
- };
183
- const response = await oauth.authorizationCodeGrantRequest(authorizationServer, client, clientAuth, authResponse, credentials.redirectUri, codeVerifier, options);
184
- return [response, client];
185
- };
186
- this.exchangeCodeForToken = async (authResponse, pkceValues, authorizationServer) => {
187
- const { codeVerifier, url, resourceUrl } = pkceValues;
188
- // Get the client credentials
189
- let credentials = await this.getClientCredentials(authorizationServer);
190
- let [response, client] = await this.makeTokenRequestAndClient(authorizationServer, credentials, codeVerifier, authResponse);
191
- if (response.status === 403 || response.status === 401) {
192
- this.logger.info(`Bad response status exchanging code for token: ${response.statusText}. Could be due to bad client credentials - trying to re-register`);
193
- credentials = await this.registerClient(authorizationServer);
194
- [response, client] = await this.makeTokenRequestAndClient(authorizationServer, credentials, codeVerifier, authResponse);
195
- }
196
- const result = await oauth.processAuthorizationCodeResponse(authorizationServer, client, response);
197
- // Save the access token in the database
198
- await this.db.saveAccessToken(this.userId, url, {
199
- resourceUrl,
200
- accessToken: result.access_token,
201
- refreshToken: result.refresh_token,
202
- expiresAt: result.expires_in
203
- ? Date.now() + result.expires_in * 1000
204
- : undefined
205
- });
206
- return result.access_token;
207
- };
208
- this.getAccessToken = async (url) => {
209
- // Get the access token from the database
210
- url = OAuthClient.trimToPath(url);
211
- let parentPath = OAuthClient.getParentPath(url);
212
- let tokenData = await this.db.getAccessToken(this.userId, url);
213
- // If there's no token for the requested path, see if there's one for the parent
214
- while (!tokenData && parentPath) {
215
- tokenData = await this.db.getAccessToken(this.userId, parentPath);
216
- parentPath = OAuthClient.getParentPath(parentPath);
217
- }
218
- return tokenData;
219
- };
220
- this.tryRefreshToken = async (url) => {
221
- url = OAuthClient.trimToPath(url);
222
- const token = await this.getAccessToken(url);
223
- if (!token) {
224
- this.logger.info('No token found, cannot refresh');
225
- return null;
226
- }
227
- if (!token.refreshToken) {
228
- this.logger.info('No refresh token found, cannot refresh');
229
- return null;
230
- }
231
- const authorizationServer = await this.getAuthorizationServer(token.resourceUrl);
232
- const credentials = await this.getClientCredentials(authorizationServer);
233
- const [client, clientAuth] = this.makeOAuthClientAndAuth(credentials);
234
- const response = await oauth.refreshTokenGrantRequest(authorizationServer, client, clientAuth, token.refreshToken, {
235
- [oauth.customFetch]: this.sideChannelFetch,
236
- [oauth.allowInsecureRequests]: this.allowInsecureRequests
237
- });
238
- const result = await oauth.processRefreshTokenResponse(authorizationServer, client, response);
239
- const at = {
240
- resourceUrl: token.resourceUrl,
241
- accessToken: result.access_token,
242
- refreshToken: result.refresh_token,
243
- expiresAt: result.expires_in
244
- ? Date.now() + result.expires_in * 1000
245
- : undefined
246
- };
247
- await this.db.saveAccessToken(this.userId, url, at);
248
- return at;
249
- };
250
- this._doFetch = async (url, init) => {
251
- const stringUrl = url instanceof URL ? url.toString() : url;
252
- this.logger.info(`Making ${init?.method || 'GET'} request to ${stringUrl}`);
253
- const tokenData = await this.getAccessToken(stringUrl);
254
- if (!tokenData) {
255
- this.logger.info(`No access token found for resource server ${stringUrl}. Passing no authorization header.`);
256
- }
257
- // Create a new init object to avoid mutating the original
258
- const requestInit = { ...init };
259
- if (tokenData) {
260
- // Create a new Headers object from existing headers (if any)
261
- const headers = new Headers(requestInit.headers);
262
- headers.set('Authorization', `Bearer ${tokenData.accessToken}`);
263
- requestInit.headers = headers;
264
- }
265
- // Make the request with the access token
266
- const response = await this.fetchFn(url, requestInit);
267
- return response;
268
- };
269
- this.db = db;
270
- this.userId = userId;
271
- this.fetchFn = fetchFn;
272
- }
273
- }
274
- //# sourceMappingURL=oAuth.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oAuth.js","sourceRoot":"","sources":["../../src/oAuth.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=setup.expo.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setup.expo.d.ts","sourceRoot":"","sources":["../../src/setup.expo.ts"],"names":[],"mappings":""}
@@ -1,42 +0,0 @@
1
- // Minimal Expo test setup
2
- import { vi } from 'vitest';
3
- // Set test environment
4
- process.env.NODE_ENV = 'test';
5
- // Skip React Native navigator setup for now - causes syntax errors
6
- // Mock Expo modules
7
- vi.mock('expo-sqlite', () => ({
8
- openDatabaseSync: vi.fn(() => ({
9
- execAsync: vi.fn(async () => { }),
10
- prepareAsync: vi.fn(async () => ({
11
- executeAsync: vi.fn(async () => ({
12
- getFirstAsync: vi.fn(async () => ({ name: 'test-name' })),
13
- })),
14
- finalizeAsync: vi.fn(async () => { }),
15
- })),
16
- closeAsync: vi.fn(async () => { }),
17
- })),
18
- }));
19
- vi.mock('expo-crypto', () => ({
20
- digestStringAsync: vi.fn(async (algorithm, data) => {
21
- // Simple mock implementation that returns a hex string
22
- const encoder = new TextEncoder();
23
- const dataBuffer = encoder.encode(data);
24
- const hashBuffer = new Uint8Array(32); // SHA256 is 32 bytes
25
- // Simple hash simulation - just use the first 32 bytes of the input
26
- for (let i = 0; i < Math.min(32, dataBuffer.length); i++) {
27
- hashBuffer[i] = dataBuffer[i];
28
- }
29
- return Array.from(hashBuffer).map(b => b.toString(16).padStart(2, '0')).join('');
30
- }),
31
- CryptoDigestAlgorithm: {
32
- SHA256: 'SHA256',
33
- },
34
- randomUUID: vi.fn(() => 'test-uuid-' + Math.random().toString(36).substr(2, 9)),
35
- }));
36
- vi.mock('react-native-url-polyfill', () => ({
37
- URL: global.URL,
38
- }));
39
- vi.mock('react-native-url-polyfill/auto', () => ({}));
40
- // Set up test environment
41
- process.env.NODE_ENV = 'test';
42
- //# sourceMappingURL=setup.expo.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setup.expo.js","sourceRoot":"","sources":["../../src/setup.expo.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,uBAAuB;AACvB,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC;AAE9B,mEAAmE;AAEnE,oBAAoB;AACpB,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,gBAAgB,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7B,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;QAChC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAC/B,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAC/B,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;aAC1D,CAAC,CAAC;YACH,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;SACrC,CAAC,CAAC;QACH,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;KAClC,CAAC,CAAC;CACJ,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,iBAAiB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,SAAiB,EAAE,IAAY,EAAE,EAAE;QACjE,uDAAuD;QACvD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB;QAC5D,oEAAoE;QACpE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzD,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC,CAAC;IACF,qBAAqB,EAAE;QACrB,MAAM,EAAE,QAAQ;KACjB;IACD,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAChF,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,2BAA2B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1C,GAAG,EAAE,MAAM,CAAC,GAAG;CAChB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEtD,0BAA0B;AAC1B,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC"}
@@ -1,9 +0,0 @@
1
- import type { Account, PaymentMaker } from './types.js';
2
- export declare class SolanaAccount implements Account {
3
- accountId: string;
4
- paymentMakers: {
5
- [key: string]: PaymentMaker;
6
- };
7
- constructor(solanaEndpoint: string, sourceSecretKey: string);
8
- }
9
- //# sourceMappingURL=solanaAccount.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"solanaAccount.d.ts","sourceRoot":"","sources":["../../src/solanaAccount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKxD,qBAAa,aAAc,YAAW,OAAO;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAA;KAAE,CAAC;gBAEnC,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM;CAc5D"}
@@ -1,19 +0,0 @@
1
- import { SolanaPaymentMaker } from './solanaPaymentMaker.js';
2
- import { Keypair } from "@solana/web3.js";
3
- import bs58 from "bs58";
4
- export class SolanaAccount {
5
- constructor(solanaEndpoint, sourceSecretKey) {
6
- if (!solanaEndpoint) {
7
- throw new Error('Solana endpoint is required');
8
- }
9
- if (!sourceSecretKey) {
10
- throw new Error('Source secret key is required');
11
- }
12
- const source = Keypair.fromSecretKey(bs58.decode(sourceSecretKey));
13
- this.accountId = source.publicKey.toBase58();
14
- this.paymentMakers = {
15
- 'solana': new SolanaPaymentMaker(solanaEndpoint, sourceSecretKey),
16
- };
17
- }
18
- }
19
- //# sourceMappingURL=solanaAccount.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"solanaAccount.js","sourceRoot":"","sources":["../../src/solanaAccount.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,OAAO,aAAa;IAIxB,YAAY,cAAsB,EAAE,eAAuB;QACzD,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;QAEnE,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC7C,IAAI,CAAC,aAAa,GAAG;YACnB,QAAQ,EAAE,IAAI,kBAAkB,CAAC,cAAc,EAAE,eAAe,CAAC;SAClE,CAAA;IACH,CAAC;CACF"}
@@ -1,17 +0,0 @@
1
- import type { PaymentMaker } from './types.js';
2
- import { ValidateTransferError as _ValidateTransferError } from "@solana/pay";
3
- import BigNumber from "bignumber.js";
4
- import { Logger } from '@longrun/atxp-common';
5
- export declare const ValidateTransferError: typeof _ValidateTransferError;
6
- export declare class SolanaPaymentMaker implements PaymentMaker {
7
- private connection;
8
- private source;
9
- private logger;
10
- constructor(solanaEndpoint: string, sourceSecretKey: string, logger?: Logger);
11
- generateJWT: ({ paymentRequestId, codeChallenge }: {
12
- paymentRequestId: string;
13
- codeChallenge: string;
14
- }) => Promise<string>;
15
- makePayment: (amount: BigNumber, currency: string, receiver: string) => Promise<string>;
16
- }
17
- //# sourceMappingURL=solanaPaymentMaker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"solanaPaymentMaker.d.ts","sourceRoot":"","sources":["../../src/solanaPaymentMaker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAkB,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE9F,OAAO,SAAS,MAAM,cAAc,CAAC;AAGrC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAM9C,eAAO,MAAM,qBAAqB,+BAAyB,CAAC;AAE5D,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAY5E,WAAW,GAAS,qCAAmC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAC,KAAG,OAAO,CAAC,MAAM,CAAC,CAezH;IAED,WAAW,GAAU,QAAQ,SAAS,EAAE,UAAU,MAAM,EAAE,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,CAqC3F;CACF"}