@keetanetwork/anchor 0.0.43 → 0.0.44
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/client/index.d.ts +6 -0
- package/client/index.d.ts.map +1 -1
- package/client/index.js +7 -0
- package/client/index.js.map +1 -1
- package/lib/resolver.d.ts +26 -0
- package/lib/resolver.d.ts.map +1 -1
- package/lib/resolver.js +683 -239
- package/lib/resolver.js.map +1 -1
- package/lib/utils/json.d.ts +4 -2
- package/lib/utils/json.d.ts.map +1 -1
- package/lib/utils/json.js +3 -2
- package/lib/utils/json.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/services/notification/client.d.ts +78 -0
- package/services/notification/client.d.ts.map +1 -0
- package/services/notification/client.js +499 -0
- package/services/notification/client.js.map +1 -0
- package/services/notification/common.d.ts +179 -0
- package/services/notification/common.d.ts.map +1 -0
- package/services/notification/common.generated.d.ts +17 -0
- package/services/notification/common.generated.d.ts.map +1 -0
- package/services/notification/common.generated.js +733 -0
- package/services/notification/common.generated.js.map +1 -0
- package/services/notification/common.js +139 -0
- package/services/notification/common.js.map +1 -0
- package/services/notification/server.d.ts +39 -0
- package/services/notification/server.d.ts.map +1 -0
- package/services/notification/server.js +222 -0
- package/services/notification/server.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.generated.js","sourceRoot":"","sources":["../../../src/services/notification/common.generated.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAkBrD,MAAM,CAAC,MAAM,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAA4J,CAAC;AAC7N,MAAM,CAAC,MAAM,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAkK,CAAC;AACtO,MAAM,CAAC,MAAM,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAA8J,CAAC;AAChO,MAAM,CAAC,MAAM,gDAAgD;;;;;;;sFAA0I,CAAC;AACxM,MAAM,CAAC,MAAM,mDAAmD;;;;;;;sFAAgJ,CAAC;AACjN,MAAM,CAAC,MAAM,iDAAiD;;;;;;;sFAA4I,CAAC;AAE3M,MAAM,CAAC,MAAM,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAA0K,CAAC;AAClP,MAAM,CAAC,MAAM,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAA0K,CAAC;AAClP,MAAM,CAAC,MAAM,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAwK,CAAC;AAC/O,MAAM,CAAC,MAAM,uDAAuD;;;;;;;sFAAwJ,CAAC;AAC7N,MAAM,CAAC,MAAM,uDAAuD;;;;;;;sFAAwJ,CAAC;AAC7N,MAAM,CAAC,MAAM,sDAAsD;;;;;;;sFAAsJ,CAAC;AAE1N,MAAM,CAAC,MAAM,6BAA6B;;;;;;;;;;;OAA6F,CAAC;AACxI,MAAM,CAAC,MAAM,kCAAkC;;;;;;;;;;;OAAuG,CAAC","sourcesContent":["import { createAssertEquals, createIs } from 'typia';\nimport type {\n\tKeetaNotificationAnchorListTargetsRequestJSON,\n\tKeetaNotificationAnchorDeleteTargetResponseJSON,\n\tKeetaNotificationAnchorDeleteTargetRequestJSON,\n\tKeetaNotificationAnchorListTargetsResponseJSON,\n\tKeetaNotificationAnchorRegisterTargetRequestJSON,\n\tKeetaNotificationAnchorRegisterTargetResponseJSON,\n\tKeetaNotificationAnchorCreateSubscriptionRequestJSON,\n\tKeetaNotificationAnchorCreateSubscriptionResponseJSON,\n\tKeetaNotificationAnchorDeleteSubscriptionRequestJSON,\n\tKeetaNotificationAnchorDeleteSubscriptionResponseJSON,\n\tKeetaNotificationAnchorListSubscriptionsRequestJSON,\n\tKeetaNotificationAnchorListSubscriptionsResponseJSON,\n\tNotificationChannelType,\n\tNotificationSubscriptionType\n} from './common.js';\n\nexport const assertKeetaNotificationAnchorListTargetsRequestJSON: ReturnType<typeof createAssertEquals<KeetaNotificationAnchorListTargetsRequestJSON>> = createAssertEquals<KeetaNotificationAnchorListTargetsRequestJSON>();\nexport const assertKeetaNotificationAnchorRegisterTargetRequestJSON: ReturnType<typeof createAssertEquals<KeetaNotificationAnchorRegisterTargetRequestJSON>> = createAssertEquals<KeetaNotificationAnchorRegisterTargetRequestJSON>();\nexport const assertKeetaNotificationAnchorDeleteTargetRequestJSON: ReturnType<typeof createAssertEquals<KeetaNotificationAnchorDeleteTargetRequestJSON>> = createAssertEquals<KeetaNotificationAnchorDeleteTargetRequestJSON>();\nexport const isKeetaNotificationAnchorListTargetsResponseJSON: (input: unknown) => input is KeetaNotificationAnchorListTargetsResponseJSON = createIs<KeetaNotificationAnchorListTargetsResponseJSON>();\nexport const isKeetaNotificationAnchorRegisterTargetResponseJSON: (input: unknown) => input is KeetaNotificationAnchorRegisterTargetResponseJSON = createIs<KeetaNotificationAnchorRegisterTargetResponseJSON>();\nexport const isKeetaNotificationAnchorDeleteTargetResponseJSON: (input: unknown) => input is KeetaNotificationAnchorDeleteTargetResponseJSON = createIs<KeetaNotificationAnchorDeleteTargetResponseJSON>();\n\nexport const assertKeetaNotificationAnchorCreateSubscriptionRequestJSON: ReturnType<typeof createAssertEquals<KeetaNotificationAnchorCreateSubscriptionRequestJSON>> = createAssertEquals<KeetaNotificationAnchorCreateSubscriptionRequestJSON>();\nexport const assertKeetaNotificationAnchorDeleteSubscriptionRequestJSON: ReturnType<typeof createAssertEquals<KeetaNotificationAnchorDeleteSubscriptionRequestJSON>> = createAssertEquals<KeetaNotificationAnchorDeleteSubscriptionRequestJSON>();\nexport const assertKeetaNotificationAnchorListSubscriptionsRequestJSON: ReturnType<typeof createAssertEquals<KeetaNotificationAnchorListSubscriptionsRequestJSON>> = createAssertEquals<KeetaNotificationAnchorListSubscriptionsRequestJSON>();\nexport const isKeetaNotificationAnchorCreateSubscriptionResponseJSON: (input: unknown) => input is KeetaNotificationAnchorCreateSubscriptionResponseJSON = createIs<KeetaNotificationAnchorCreateSubscriptionResponseJSON>();\nexport const isKeetaNotificationAnchorDeleteSubscriptionResponseJSON: (input: unknown) => input is KeetaNotificationAnchorDeleteSubscriptionResponseJSON = createIs<KeetaNotificationAnchorDeleteSubscriptionResponseJSON>();\nexport const isKeetaNotificationAnchorListSubscriptionsResponseJSON: (input: unknown) => input is KeetaNotificationAnchorListSubscriptionsResponseJSON = createIs<KeetaNotificationAnchorListSubscriptionsResponseJSON>();\n\nexport const assertNotificationChannelType: (input: unknown) => NotificationChannelType = createAssertEquals<NotificationChannelType>();\nexport const assertNotificationSubscriptionType: (input: unknown) => NotificationSubscriptionType = createAssertEquals<NotificationSubscriptionType>();\n"]}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { assertNever } from '../../lib/utils/never.js';
|
|
2
|
+
import { KeetaAnchorUserError } from '../../lib/error.js';
|
|
3
|
+
import { assertNotificationChannelType, assertNotificationSubscriptionType } from './common.generated.js';
|
|
4
|
+
import { KeetaNet } from '../../client/index.js';
|
|
5
|
+
export * from './common.generated.js';
|
|
6
|
+
const notificationNamespace = '75ed4792-333f-4a50-832f-b9fcc5663d1f';
|
|
7
|
+
export function getNotificationRegisterTargetRequestSignable(request) {
|
|
8
|
+
const parts = [
|
|
9
|
+
notificationNamespace,
|
|
10
|
+
'REGISTER_TARGET',
|
|
11
|
+
request.channel.type
|
|
12
|
+
];
|
|
13
|
+
if (request.channel.type === 'FCM') {
|
|
14
|
+
parts.push(request.channel.fcmToken, request.channel.appId);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
assertNever(request.channel.type);
|
|
18
|
+
}
|
|
19
|
+
return (parts);
|
|
20
|
+
}
|
|
21
|
+
export function getNotificationListTargetsRequestSignable(_ignore_request) {
|
|
22
|
+
return ([
|
|
23
|
+
notificationNamespace,
|
|
24
|
+
'LIST_TARGETS'
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
export function getNotificationDeleteTargetRequestSignable(request) {
|
|
28
|
+
return ([
|
|
29
|
+
notificationNamespace,
|
|
30
|
+
'DELETE_TARGET',
|
|
31
|
+
request.id
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
export function getNotificationCreateSubscriptionRequestSignable(request) {
|
|
35
|
+
const parts = [
|
|
36
|
+
notificationNamespace,
|
|
37
|
+
'CREATE_SUBSCRIPTION',
|
|
38
|
+
request.subscription.type
|
|
39
|
+
];
|
|
40
|
+
parts.push(request.subscription.locale?.toString() ?? 'NO_LOCALE');
|
|
41
|
+
if (request.subscription.type === 'RECEIVE_FUNDS') {
|
|
42
|
+
parts.push(request.subscription.toAddress ?? 'NO_ADDRESS');
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
assertNever(request.subscription.type);
|
|
46
|
+
}
|
|
47
|
+
parts.push(request.subscription.target.provider ?? 'NO_PROVIDER');
|
|
48
|
+
parts.push('BEGIN_TARGETS');
|
|
49
|
+
for (const target of request.subscription.target.ids) {
|
|
50
|
+
parts.push(target);
|
|
51
|
+
}
|
|
52
|
+
parts.push('END_TARGETS');
|
|
53
|
+
return (parts);
|
|
54
|
+
}
|
|
55
|
+
export function getNotificationDeleteSubscriptionRequestSignable(request) {
|
|
56
|
+
return ([
|
|
57
|
+
notificationNamespace,
|
|
58
|
+
'DELETE_SUBSCRIPTION',
|
|
59
|
+
request.id
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
export function parseSubscriptionDetailsWithID(input) {
|
|
63
|
+
let subscription;
|
|
64
|
+
if (input.subscription.type === 'RECEIVE_FUNDS') {
|
|
65
|
+
let locale;
|
|
66
|
+
if (input.subscription.locale) {
|
|
67
|
+
if (typeof input.subscription.locale === 'string') {
|
|
68
|
+
locale = new Intl.Locale(input.subscription.locale);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
locale = input.subscription.locale;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
subscription = {
|
|
75
|
+
type: 'RECEIVE_FUNDS',
|
|
76
|
+
target: input.subscription.target,
|
|
77
|
+
...(locale ? { locale } : {}),
|
|
78
|
+
...(input.subscription.toAddress
|
|
79
|
+
? { toAddress: KeetaNet.lib.Account.toAccount(input.subscription.toAddress) }
|
|
80
|
+
: {})
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
assertNever(input.subscription.type);
|
|
85
|
+
}
|
|
86
|
+
return ({ id: input.id, subscription });
|
|
87
|
+
}
|
|
88
|
+
export function getNotificationListSubscriptionsRequestSignable(_ignore_request) {
|
|
89
|
+
return ([
|
|
90
|
+
notificationNamespace,
|
|
91
|
+
'LIST_SUBSCRIPTIONS'
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
94
|
+
class KeetaNotificationAnchorMethodNotSupportedError extends KeetaAnchorUserError {
|
|
95
|
+
static name = 'KeetaNotificationAnchorMethodNotSupportedError';
|
|
96
|
+
KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID;
|
|
97
|
+
static KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID = '95268e45-2305-4a75-92af-417feb57fdd6';
|
|
98
|
+
logLevel = 'INFO';
|
|
99
|
+
channelType;
|
|
100
|
+
subscriptionType;
|
|
101
|
+
constructor(properties, message) {
|
|
102
|
+
super(message ?? `Request failed: ${properties.channelType ? `channel type ${properties.channelType}` : `subscription type ${properties.subscriptionType}`} not supported`);
|
|
103
|
+
this.statusCode = 400;
|
|
104
|
+
Object.defineProperty(this, 'KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID', {
|
|
105
|
+
value: KeetaNotificationAnchorMethodNotSupportedError.KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID,
|
|
106
|
+
enumerable: false
|
|
107
|
+
});
|
|
108
|
+
this.channelType = properties.channelType;
|
|
109
|
+
this.subscriptionType = properties.subscriptionType;
|
|
110
|
+
}
|
|
111
|
+
static isInstance(input) {
|
|
112
|
+
return (this.hasPropWithValue(input, 'KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID', KeetaNotificationAnchorMethodNotSupportedError.KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID));
|
|
113
|
+
}
|
|
114
|
+
toJSON() {
|
|
115
|
+
return ({
|
|
116
|
+
...super.toJSON(),
|
|
117
|
+
channelType: this.channelType,
|
|
118
|
+
subscriptionType: this.subscriptionType
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
static async fromJSON(input) {
|
|
122
|
+
const { message, other } = this.extractErrorProperties(input, this);
|
|
123
|
+
let subscriptionType;
|
|
124
|
+
if ('intent' in other && other.intent !== undefined) {
|
|
125
|
+
subscriptionType = assertNotificationSubscriptionType(other.subscriptionType);
|
|
126
|
+
}
|
|
127
|
+
let channelType;
|
|
128
|
+
if ('channelType' in other && other.channelType !== undefined) {
|
|
129
|
+
channelType = assertNotificationChannelType(other.channelType);
|
|
130
|
+
}
|
|
131
|
+
const error = new this({ subscriptionType, channelType }, message);
|
|
132
|
+
error.restoreFromJSON(other);
|
|
133
|
+
return (error);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export const Errors = {
|
|
137
|
+
MethodNotSupported: KeetaNotificationAnchorMethodNotSupportedError
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/services/notification/common.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ToJSONSerializable } from '../../lib/utils/json.js';\nimport type { HTTPSignedField } from '../../lib/http-server/common.js';\nimport type { Signable } from '../../lib/utils/signing.js';\nimport type { Account, GenericAccount } from '@keetanetwork/keetanet-client/lib/account.js';\nimport { assertNever } from '../../lib/utils/never.js';\nimport { KeetaAnchorUserError } from '../../lib/error.js';\nimport { assertNotificationChannelType, assertNotificationSubscriptionType } from './common.generated.js';\nimport { KeetaNet } from '../../client/index.js';\nexport * from './common.generated.js';\n\ninterface BaseNotificationChannelArguments<T extends string> {\n\ttype: T;\n}\n\ninterface FCMNotificationChannelArguments extends BaseNotificationChannelArguments<'FCM'> {\n\tappId: string;\n\tfcmToken: string;\n}\n\nexport type NotificationChannelArguments = FCMNotificationChannelArguments;\n\nexport type NotificationChannelType = NotificationChannelArguments['type'];\n\ninterface NotificationChannelServiceMetadata {\n\tFCM: {\n\t\tprojectId: string;\n\t\tmessagingSenderId: string;\n\t\tappId: string;\n\t\tapiKey: string;\n\t\tvapidKey?: string;\n\t}\n}\n\ninterface BaseNotificationSubscriptionArguments<T extends string> {\n\ttype: T;\n\n\t// The preferred locale to receive notifications in, if supported by the channel and provider\n\tlocale?: Intl.Locale;\n\n\ttarget: {\n\t\tprovider?: string | undefined;\n\n\t\tids: string[];\n\t}\n}\n\ninterface ReceiveFundsNotificationSubscriptionArguments extends BaseNotificationSubscriptionArguments<'RECEIVE_FUNDS'> {\n\t// Address to listen to incoming transactions for, if omitted will use the requestors address\n\ttoAddress?: GenericAccount;\n}\n\nexport type NotificationSubscriptionArguments = ReceiveFundsNotificationSubscriptionArguments;\nexport type NotificationSubscriptionArgumentsJSON = ToJSONSerializable<Omit<NotificationSubscriptionArguments, 'locale'>> & {\n\tlocale?: string | undefined;\n};\nexport type NotificationSubscriptionType = NotificationSubscriptionArguments['type'];\n\nexport type SupportedChannelConfigurationMetadata = {\n\tFCM: NotificationChannelServiceMetadata['FCM'][];\n}\n\n// API types\n\nexport interface NotificationTargetWithIDResponse {\n\tid: string;\n\tchannel: NotificationChannelArguments;\n}\n\nconst notificationNamespace = '75ed4792-333f-4a50-832f-b9fcc5663d1f';\n\nexport interface KeetaNotificationAnchorRegisterTargetClientRequest {\n\taccount?: Account;\n\tchannel: NotificationChannelArguments;\n}\nexport interface KeetaNotificationAnchorRegisterTargetRequest extends KeetaNotificationAnchorRegisterTargetClientRequest {\n\taccount: Account;\n\tsigned: HTTPSignedField;\n}\nexport type KeetaNotificationAnchorRegisterTargetRequestJSON = ToJSONSerializable<KeetaNotificationAnchorRegisterTargetRequest>;\n\nexport type KeetaNotificationAnchorRegisterTargetResponseJSON = ({\n\tok: true;\n\tid: string;\n}) | ({\n\tok: false;\n\terror: string;\n});\n\nexport function getNotificationRegisterTargetRequestSignable(request: Pick<KeetaNotificationAnchorRegisterTargetClientRequest, 'channel'>): Signable {\n\tconst parts: Signable = [\n\t\tnotificationNamespace,\n\t\t'REGISTER_TARGET',\n\t\trequest.channel.type\n\t];\n\n\tif (request.channel.type === 'FCM') {\n\t\tparts.push(request.channel.fcmToken, request.channel.appId);\n\t} else {\n\t\tassertNever(request.channel.type);\n\t}\n\n\treturn(parts);\n}\n\nexport interface KeetaNotificationAnchorListTargetsClientRequest { account?: Account; }\ninterface KeetaNotificationAnchorListTargetsRequest extends KeetaNotificationAnchorListTargetsClientRequest {\n\taccount: Account;\n\tsigned: HTTPSignedField;\n}\nexport type KeetaNotificationAnchorListTargetsRequestJSON = ToJSONSerializable<KeetaNotificationAnchorListTargetsRequest>;\n\nexport type KeetaNotificationAnchorListTargetsResponse = ({\n\tok: true;\n\ttargets: NotificationTargetWithIDResponse[];\n}) | ({\n\tok: false;\n\terror: string;\n});\nexport type KeetaNotificationAnchorListTargetsResponseJSON = ToJSONSerializable<KeetaNotificationAnchorListTargetsResponse>;\n\nexport function getNotificationListTargetsRequestSignable(_ignore_request?: KeetaNotificationAnchorListTargetsClientRequest): Signable {\n\treturn([\n\t\tnotificationNamespace,\n\t\t'LIST_TARGETS'\n\t]);\n}\n\n\nexport interface KeetaNotificationAnchorDeleteTargetClientRequest {\n\taccount?: Account;\n\tid: string;\n}\nexport interface KeetaNotificationAnchorDeleteTargetRequest extends KeetaNotificationAnchorDeleteTargetClientRequest {\n\taccount: Account;\n\tsigned: HTTPSignedField;\n}\nexport type KeetaNotificationAnchorDeleteTargetRequestJSON = ToJSONSerializable<KeetaNotificationAnchorDeleteTargetRequest>;\n\nexport type KeetaNotificationAnchorDeleteTargetResponse = ({\n\tok: true;\n}) | ({\n\tok: false;\n\terror: string;\n});\n\nexport type KeetaNotificationAnchorDeleteTargetResponseJSON = ToJSONSerializable<KeetaNotificationAnchorDeleteTargetResponse>;\n\nexport function getNotificationDeleteTargetRequestSignable(request: Pick<KeetaNotificationAnchorDeleteTargetClientRequest, 'id'>): Signable {\n\treturn([\n\t\tnotificationNamespace,\n\t\t'DELETE_TARGET',\n\t\trequest.id\n\t]);\n}\n\nexport interface KeetaNotificationAnchorCreateSubscriptionClientRequest {\n\taccount?: Account;\n\tsubscription: NotificationSubscriptionArguments;\n}\n\nexport type KeetaNotificationAnchorCreateSubscriptionRequestJSON = {\n\tsubscription: NotificationSubscriptionArgumentsJSON;\n\taccount: string;\n\tsigned: HTTPSignedField;\n}\n\nexport type KeetaNotificationAnchorCreateSubscriptionResponse = ({\n\tok: true;\n\tid: string;\n}) | ({\n\tok: false;\n\terror: string;\n});\n\nexport type KeetaNotificationAnchorCreateSubscriptionResponseJSON = ToJSONSerializable<KeetaNotificationAnchorCreateSubscriptionResponse>;\n\nexport function getNotificationCreateSubscriptionRequestSignable(request: Pick<KeetaNotificationAnchorCreateSubscriptionClientRequest, 'subscription'>): Signable {\n\tconst parts: Signable = [\n\t\tnotificationNamespace,\n\t\t'CREATE_SUBSCRIPTION',\n\t\trequest.subscription.type\n\t];\n\n\tparts.push(request.subscription.locale?.toString() ?? 'NO_LOCALE');\n\n\tif (request.subscription.type === 'RECEIVE_FUNDS') {\n\t\tparts.push(request.subscription.toAddress ?? 'NO_ADDRESS');\n\t} else {\n\t\tassertNever(request.subscription.type);\n\t}\n\n\tparts.push(request.subscription.target.provider ?? 'NO_PROVIDER');\n\n\tparts.push('BEGIN_TARGETS');\n\tfor (const target of request.subscription.target.ids) {\n\t\tparts.push(target);\n\t}\n\tparts.push('END_TARGETS');\n\n\treturn(parts);\n}\n\nexport interface KeetaNotificationAnchorDeleteSubscriptionClientRequest {\n\taccount?: Account;\n\tid: string;\n}\nexport interface KeetaNotificationAnchorDeleteSubscriptionRequest extends KeetaNotificationAnchorDeleteSubscriptionClientRequest {\n\taccount: Account;\n\tsigned: HTTPSignedField;\n}\nexport type KeetaNotificationAnchorDeleteSubscriptionRequestJSON = ToJSONSerializable<KeetaNotificationAnchorDeleteSubscriptionRequest>;\n\nexport type KeetaNotificationAnchorDeleteSubscriptionResponse = ({\n\tok: true;\n}) | ({\n\tok: false;\n\terror: string;\n});\n\nexport type KeetaNotificationAnchorDeleteSubscriptionResponseJSON = ToJSONSerializable<KeetaNotificationAnchorDeleteSubscriptionResponse>;\n\nexport function getNotificationDeleteSubscriptionRequestSignable(request: Pick<KeetaNotificationAnchorDeleteSubscriptionClientRequest, 'id'>): Signable {\n\treturn([\n\t\tnotificationNamespace,\n\t\t'DELETE_SUBSCRIPTION',\n\t\trequest.id\n\t]);\n}\n\nexport interface SubscriptionDetails {\n\tid: string;\n\tsubscription: NotificationSubscriptionArguments;\n}\n\nexport type SubscriptionDetailsJSON = ToJSONSerializable<Omit<SubscriptionDetails, 'subscription'>> & {\n\tsubscription: NotificationSubscriptionArgumentsJSON;\n}\n\nexport function parseSubscriptionDetailsWithID(input: SubscriptionDetailsJSON | SubscriptionDetails): SubscriptionDetails {\n\tlet subscription: NotificationSubscriptionArguments;\n\tif (input.subscription.type === 'RECEIVE_FUNDS') {\n\t\tlet locale;\n\t\tif (input.subscription.locale) {\n\t\t\tif (typeof input.subscription.locale === 'string') {\n\t\t\t\tlocale = new Intl.Locale(input.subscription.locale);\n\t\t\t} else {\n\t\t\t\tlocale = input.subscription.locale;\n\t\t\t}\n\t\t}\n\n\t\tsubscription = {\n\t\t\ttype: 'RECEIVE_FUNDS',\n\t\t\ttarget: input.subscription.target,\n\t\t\t...(locale ? { locale } : {}),\n\t\t\t...(input.subscription.toAddress\n\t\t\t\t? { toAddress: KeetaNet.lib.Account.toAccount(input.subscription.toAddress) }\n\t\t\t\t: {})\n\t\t};\n\t} else {\n\t\tassertNever(input.subscription.type);\n\t}\n\n\treturn({ id: input.id, subscription });\n}\n\nexport interface KeetaNotificationAnchorListSubscriptionsClientRequest { account?: Account; }\ninterface KeetaNotificationAnchorListSubscriptionsRequest extends KeetaNotificationAnchorListSubscriptionsClientRequest {\n\taccount: Account;\n\tsigned: HTTPSignedField;\n}\nexport type KeetaNotificationAnchorListSubscriptionsRequestJSON = ToJSONSerializable<KeetaNotificationAnchorListSubscriptionsRequest>;\n\nexport type KeetaNotificationAnchorListSubscriptionsResponse = ({\n\tok: true;\n\tsubscriptions: SubscriptionDetailsJSON[];\n}) | ({\n\tok: false;\n\terror: string;\n});\n\nexport type KeetaNotificationAnchorListSubscriptionsResponseJSON = ToJSONSerializable<KeetaNotificationAnchorListSubscriptionsResponse>;\n\nexport function getNotificationListSubscriptionsRequestSignable(_ignore_request?: KeetaNotificationAnchorListSubscriptionsClientRequest): Signable {\n\treturn([\n\t\tnotificationNamespace,\n\t\t'LIST_SUBSCRIPTIONS'\n\t]);\n}\n\ninterface KeetaNotificationAnchorMethodNotSupportedErrorProperties {\n\tchannelType?: NotificationChannelType | undefined;\n\tsubscriptionType?: NotificationSubscriptionType | undefined;\n}\n\ntype KeetaNotificationAnchorMethodNotSupportedErrorJSON = ReturnType<KeetaAnchorUserError['toJSON']> & KeetaNotificationAnchorMethodNotSupportedErrorProperties;\n\nclass KeetaNotificationAnchorMethodNotSupportedError extends KeetaAnchorUserError implements KeetaNotificationAnchorMethodNotSupportedErrorProperties {\n\tstatic override readonly name: string = 'KeetaNotificationAnchorMethodNotSupportedError';\n\tprivate readonly KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID!: string;\n\tprivate static readonly KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID = '95268e45-2305-4a75-92af-417feb57fdd6';\n\toverride readonly logLevel = 'INFO';\n\treadonly channelType?: NotificationChannelType | undefined;\n\treadonly subscriptionType?: NotificationSubscriptionType | undefined;\n\n\tconstructor(properties: KeetaNotificationAnchorMethodNotSupportedErrorProperties, message?: string) {\n\t\tsuper(message ?? `Request failed: ${properties.channelType ? `channel type ${properties.channelType}` : `subscription type ${properties.subscriptionType}`} not supported`);\n\t\tthis.statusCode = 400;\n\n\t\tObject.defineProperty(this, 'KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID', {\n\t\t\tvalue: KeetaNotificationAnchorMethodNotSupportedError.KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\n\t\tthis.channelType = properties.channelType;\n\t\tthis.subscriptionType = properties.subscriptionType;\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaNotificationAnchorMethodNotSupportedError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID', KeetaNotificationAnchorMethodNotSupportedError.KeetaNotificationAnchorMethodNotSupportedErrorObjectTypeID));\n\t}\n\n\ttoJSON(): KeetaNotificationAnchorMethodNotSupportedErrorJSON {\n\t\treturn({\n\t\t\t...super.toJSON(),\n\t\t\tchannelType: this.channelType,\n\t\t\tsubscriptionType: this.subscriptionType\n\t\t});\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaNotificationAnchorMethodNotSupportedError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\n\t\tlet subscriptionType: NotificationSubscriptionType | undefined;\n\t\tif ('intent' in other && other.intent !== undefined) {\n\t\t\tsubscriptionType = assertNotificationSubscriptionType(other.subscriptionType);\n\t\t}\n\n\t\tlet channelType: NotificationChannelType | undefined;\n\t\tif ('channelType' in other && other.channelType !== undefined) {\n\t\t\tchannelType = assertNotificationChannelType(other.channelType);\n\t\t}\n\n\t\tconst error = new this({ subscriptionType, channelType }, message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nexport const Errors: {\n\tMethodNotSupported: typeof KeetaNotificationAnchorMethodNotSupportedError;\n} = {\n\tMethodNotSupported: KeetaNotificationAnchorMethodNotSupportedError\n};\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';
|
|
2
|
+
import type { KeetaNotificationAnchorRegisterTargetClientRequest, KeetaNotificationAnchorListTargetsClientRequest, NotificationTargetWithIDResponse, KeetaNotificationAnchorDeleteTargetClientRequest, KeetaNotificationAnchorCreateSubscriptionClientRequest, KeetaNotificationAnchorDeleteSubscriptionClientRequest, KeetaNotificationAnchorListSubscriptionsClientRequest, SubscriptionDetails, NotificationSubscriptionType, SupportedChannelConfigurationMetadata } from './common.js';
|
|
3
|
+
import type { ServiceMetadata } from '../../lib/resolver.js';
|
|
4
|
+
import type { Routes } from '../../lib/http-server/index.js';
|
|
5
|
+
export interface KeetaAnchorNotificationServerConfig extends KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig {
|
|
6
|
+
homepage?: string | (() => Promise<string> | string);
|
|
7
|
+
notification: {
|
|
8
|
+
registerTarget?: (args: Required<KeetaNotificationAnchorRegisterTargetClientRequest>) => Promise<{
|
|
9
|
+
id: string;
|
|
10
|
+
}>;
|
|
11
|
+
listTargets?: (args: Required<KeetaNotificationAnchorListTargetsClientRequest>) => Promise<{
|
|
12
|
+
targets: NotificationTargetWithIDResponse[];
|
|
13
|
+
}>;
|
|
14
|
+
deleteTarget?: (args: Required<KeetaNotificationAnchorDeleteTargetClientRequest>) => Promise<{
|
|
15
|
+
ok: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
createSubscription?: (args: Required<KeetaNotificationAnchorCreateSubscriptionClientRequest>) => Promise<{
|
|
18
|
+
id: string;
|
|
19
|
+
}>;
|
|
20
|
+
listSubscriptions?: (args: Required<KeetaNotificationAnchorListSubscriptionsClientRequest>) => Promise<{
|
|
21
|
+
subscriptions: SubscriptionDetails[];
|
|
22
|
+
}>;
|
|
23
|
+
deleteSubscription?: (args: Required<KeetaNotificationAnchorDeleteSubscriptionClientRequest>) => Promise<{
|
|
24
|
+
ok: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
supportedChannels?: SupportedChannelConfigurationMetadata;
|
|
27
|
+
supportedSubscriptions?: NotificationSubscriptionType[];
|
|
28
|
+
};
|
|
29
|
+
routes?: Routes;
|
|
30
|
+
}
|
|
31
|
+
export declare class KeetaNetNotificationAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<KeetaAnchorNotificationServerConfig> {
|
|
32
|
+
readonly homepage: NonNullable<KeetaAnchorNotificationServerConfig['homepage']>;
|
|
33
|
+
readonly notification: KeetaAnchorNotificationServerConfig['notification'];
|
|
34
|
+
readonly routes: NonNullable<KeetaAnchorNotificationServerConfig['routes']>;
|
|
35
|
+
constructor(config: KeetaAnchorNotificationServerConfig);
|
|
36
|
+
protected initRoutes(config: KeetaAnchorNotificationServerConfig): Promise<KeetaAnchorHTTPServer.Routes>;
|
|
37
|
+
serviceMetadata(): Promise<NonNullable<ServiceMetadata['services']['notification']>[string]>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/services/notification/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,qBAAqB,MAAM,gCAAgC,CAAC;AACxE,OAAO,KAAK,EACX,kDAAkD,EAClD,+CAA+C,EAC/C,gCAAgC,EAChC,gDAAgD,EAGhD,sDAAsD,EACtD,sDAAsD,EAEtD,qDAAqD,EACrD,mBAAmB,EAEnB,4BAA4B,EAC5B,qCAAqC,EAErC,MAAM,aAAa,CAAC;AAarB,OAAO,KAAK,EAAE,eAAe,EAAqC,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAK7D,MAAM,WAAW,mCAAoC,SAAQ,qBAAqB,CAAC,2BAA2B;IAC7G,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IACrD,YAAY,EAAE;QACb,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,kDAAkD,CAAC,KAAK,OAAO,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;SAAE,CAAC,CAAC;QAClH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,+CAA+C,CAAC,KAAK,OAAO,CAAC;YAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC;SAAE,CAAC,CAAC;QAC7I,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,gDAAgD,CAAC,KAAK,OAAO,CAAC;YAAE,EAAE,EAAE,OAAO,CAAC;SAAE,CAAC,CAAC;QAE/G,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,sDAAsD,CAAC,KAAK,OAAO,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;SAAE,CAAC,CAAC;QAC1H,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,qDAAqD,CAAC,KAAK,OAAO,CAAC;YAAE,aAAa,EAAE,mBAAmB,EAAE,CAAC;SAAE,CAAC,CAAC;QAClJ,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,sDAAsD,CAAC,KAAK,OAAO,CAAC;YAAE,EAAE,EAAE,OAAO,CAAC;SAAE,CAAC,CAAC;QAE3H,iBAAiB,CAAC,EAAE,qCAAqC,CAAC;QAC1D,sBAAsB,CAAC,EAAE,4BAA4B,EAAE,CAAC;KACxD,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,oCAAqC,SAAQ,qBAAqB,CAAC,wBAAwB,CAAC,mCAAmC,CAAC;IAC5I,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,mCAAmC,CAAC,UAAU,CAAC,CAAC,CAAC;IAChF,QAAQ,CAAC,YAAY,EAAE,mCAAmC,CAAC,cAAc,CAAC,CAAC;IAC3E,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,mCAAmC,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAEhE,MAAM,EAAE,mCAAmC;cAQvC,UAAU,CAAC,MAAM,EAAE,mCAAmC,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC;IA6OxG,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CA0ClG"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { KeetaNet } from '../../client/index.js';
|
|
2
|
+
import * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';
|
|
3
|
+
import { getNotificationRegisterTargetRequestSignable, assertKeetaNotificationAnchorRegisterTargetRequestJSON, getNotificationListTargetsRequestSignable, assertKeetaNotificationAnchorDeleteTargetRequestJSON, getNotificationDeleteTargetRequestSignable, assertKeetaNotificationAnchorCreateSubscriptionRequestJSON, getNotificationCreateSubscriptionRequestSignable, assertKeetaNotificationAnchorDeleteSubscriptionRequestJSON, getNotificationDeleteSubscriptionRequestSignable, getNotificationListSubscriptionsRequestSignable } from './common.js';
|
|
4
|
+
import { KeetaAnchorUserError } from '../../lib/error.js';
|
|
5
|
+
import * as Signing from '../../lib/utils/signing.js';
|
|
6
|
+
import { parseSignatureFromURL } from '../../lib/http-server/common.js';
|
|
7
|
+
export class KeetaNetNotificationAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer {
|
|
8
|
+
homepage;
|
|
9
|
+
notification;
|
|
10
|
+
routes;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
super(config);
|
|
13
|
+
this.homepage = config.homepage ?? '';
|
|
14
|
+
this.notification = config.notification;
|
|
15
|
+
this.routes = config.routes ?? {};
|
|
16
|
+
}
|
|
17
|
+
async initRoutes(config) {
|
|
18
|
+
const routes = { ...this.routes };
|
|
19
|
+
if ('homepage' in config) {
|
|
20
|
+
routes['GET /'] = async function () {
|
|
21
|
+
let homepageData;
|
|
22
|
+
if (typeof config.homepage === 'string') {
|
|
23
|
+
homepageData = config.homepage;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (!config.homepage) {
|
|
27
|
+
throw (new Error('internal error: No homepage function provided'));
|
|
28
|
+
}
|
|
29
|
+
homepageData = await config.homepage();
|
|
30
|
+
}
|
|
31
|
+
return ({
|
|
32
|
+
output: homepageData,
|
|
33
|
+
contentType: 'text/html; charset=utf-8'
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const registerTargetHandler = this.notification.registerTarget;
|
|
38
|
+
if (registerTargetHandler) {
|
|
39
|
+
routes['POST /api/target'] = async (_params, body) => {
|
|
40
|
+
const request = (() => {
|
|
41
|
+
const raw = assertKeetaNotificationAnchorRegisterTargetRequestJSON(body);
|
|
42
|
+
return ({
|
|
43
|
+
...raw,
|
|
44
|
+
account: KeetaNet.lib.Account.toAccount(raw.account)
|
|
45
|
+
});
|
|
46
|
+
})();
|
|
47
|
+
const signatureVerified = await Signing.VerifySignedData(request.account, getNotificationRegisterTargetRequestSignable(request), request.signed);
|
|
48
|
+
if (!signatureVerified) {
|
|
49
|
+
throw (new KeetaAnchorUserError('Invalid signature'));
|
|
50
|
+
}
|
|
51
|
+
const registerResponse = await registerTargetHandler(request);
|
|
52
|
+
return ({
|
|
53
|
+
output: JSON.stringify({
|
|
54
|
+
ok: true,
|
|
55
|
+
id: registerResponse.id
|
|
56
|
+
}),
|
|
57
|
+
contentType: 'application/json'
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const listTargetsHandler = this.notification.listTargets;
|
|
62
|
+
if (listTargetsHandler) {
|
|
63
|
+
routes['GET /api/targets'] = async (_ignore_params, _ignore_body, _ignore_headers, url) => {
|
|
64
|
+
const signatureDetails = parseSignatureFromURL(url);
|
|
65
|
+
if (!signatureDetails.account || !signatureDetails.signedField) {
|
|
66
|
+
throw (new KeetaAnchorUserError('Missing signature parameters in URL'));
|
|
67
|
+
}
|
|
68
|
+
const verifiedSignature = await Signing.VerifySignedData(signatureDetails.account, getNotificationListTargetsRequestSignable(), signatureDetails.signedField);
|
|
69
|
+
if (!verifiedSignature) {
|
|
70
|
+
throw (new KeetaAnchorUserError('Invalid signature'));
|
|
71
|
+
}
|
|
72
|
+
const listResponse = await listTargetsHandler({ account: signatureDetails.account });
|
|
73
|
+
return ({
|
|
74
|
+
output: JSON.stringify({
|
|
75
|
+
ok: true,
|
|
76
|
+
targets: listResponse.targets
|
|
77
|
+
}),
|
|
78
|
+
contentType: 'application/json'
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const deleteTargetHandler = this.notification.deleteTarget;
|
|
83
|
+
if (deleteTargetHandler) {
|
|
84
|
+
// XXX:TODO should this be post with body or delete with URL param? Delete with URL param is more RESTful but can be more difficult to call from some clients and doesn't allow for a request body (so all data must be in the URL or signature)
|
|
85
|
+
routes['POST /api/delete-target'] = async (_params, body) => {
|
|
86
|
+
const request = (() => {
|
|
87
|
+
const raw = assertKeetaNotificationAnchorDeleteTargetRequestJSON(body);
|
|
88
|
+
return ({
|
|
89
|
+
...raw,
|
|
90
|
+
account: KeetaNet.lib.Account.toAccount(raw.account)
|
|
91
|
+
});
|
|
92
|
+
})();
|
|
93
|
+
const verifiedSignature = await Signing.VerifySignedData(request.account, getNotificationDeleteTargetRequestSignable(request), request.signed);
|
|
94
|
+
if (!verifiedSignature) {
|
|
95
|
+
throw (new KeetaAnchorUserError('Invalid signature'));
|
|
96
|
+
}
|
|
97
|
+
const deleteResponse = await deleteTargetHandler(request);
|
|
98
|
+
return ({
|
|
99
|
+
output: JSON.stringify(deleteResponse),
|
|
100
|
+
contentType: 'application/json'
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const createSubscriptionHandler = this.notification.createSubscription;
|
|
105
|
+
if (createSubscriptionHandler) {
|
|
106
|
+
routes['POST /api/subscription'] = async (_params, body) => {
|
|
107
|
+
const raw = assertKeetaNotificationAnchorCreateSubscriptionRequestJSON(body);
|
|
108
|
+
const account = KeetaNet.lib.Account.fromPublicKeyString(raw.account);
|
|
109
|
+
let subscription;
|
|
110
|
+
if (raw.subscription.type === 'RECEIVE_FUNDS') {
|
|
111
|
+
subscription = {
|
|
112
|
+
type: 'RECEIVE_FUNDS',
|
|
113
|
+
target: raw.subscription.target,
|
|
114
|
+
...(raw.subscription.toAddress
|
|
115
|
+
? { toAddress: KeetaNet.lib.Account.fromPublicKeyString(raw.subscription.toAddress) }
|
|
116
|
+
: {}),
|
|
117
|
+
...(raw.subscription.locale ? { locale: new Intl.Locale(raw.subscription.locale) } : {})
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
throw (new KeetaAnchorUserError(`Unsupported subscription type`));
|
|
122
|
+
}
|
|
123
|
+
const request = { account: account.assertAccount(), subscription, signed: raw.signed };
|
|
124
|
+
const signatureVerified = await Signing.VerifySignedData(account, getNotificationCreateSubscriptionRequestSignable({ subscription }), raw.signed);
|
|
125
|
+
if (!signatureVerified) {
|
|
126
|
+
throw (new KeetaAnchorUserError('Invalid signature'));
|
|
127
|
+
}
|
|
128
|
+
const createResponse = await createSubscriptionHandler(request);
|
|
129
|
+
return ({
|
|
130
|
+
output: JSON.stringify({ ok: true, id: createResponse.id }),
|
|
131
|
+
contentType: 'application/json'
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const listSubscriptionsHandler = this.notification.listSubscriptions;
|
|
136
|
+
if (listSubscriptionsHandler) {
|
|
137
|
+
routes['GET /api/subscriptions'] = async (_ignore_params, _ignore_body, _ignore_headers, url) => {
|
|
138
|
+
const signatureDetails = parseSignatureFromURL(url);
|
|
139
|
+
if (!signatureDetails.account || !signatureDetails.signedField) {
|
|
140
|
+
throw (new KeetaAnchorUserError('Missing signature parameters in URL'));
|
|
141
|
+
}
|
|
142
|
+
const verifiedSignature = await Signing.VerifySignedData(signatureDetails.account, getNotificationListSubscriptionsRequestSignable(), signatureDetails.signedField);
|
|
143
|
+
if (!verifiedSignature) {
|
|
144
|
+
throw (new KeetaAnchorUserError('Invalid signature'));
|
|
145
|
+
}
|
|
146
|
+
const listResponse = await listSubscriptionsHandler({ account: signatureDetails.account });
|
|
147
|
+
const subscriptionsJSON = listResponse.subscriptions.map(function (subscription) {
|
|
148
|
+
const { locale, ...restSubscription } = subscription.subscription;
|
|
149
|
+
return ({
|
|
150
|
+
...subscription,
|
|
151
|
+
subscription: {
|
|
152
|
+
...KeetaNet.lib.Utils.Conversion.toJSONSerializable(restSubscription),
|
|
153
|
+
...(locale ? { locale: locale.toString() } : {})
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
return ({
|
|
158
|
+
output: JSON.stringify(KeetaNet.lib.Utils.Conversion.toJSONSerializable({
|
|
159
|
+
ok: true,
|
|
160
|
+
subscriptions: subscriptionsJSON
|
|
161
|
+
})),
|
|
162
|
+
contentType: 'application/json'
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const deleteSubscriptionHandler = this.notification.deleteSubscription;
|
|
167
|
+
if (deleteSubscriptionHandler) {
|
|
168
|
+
routes['POST /api/delete-subscription'] = async (_params, body) => {
|
|
169
|
+
const request = (() => {
|
|
170
|
+
const raw = assertKeetaNotificationAnchorDeleteSubscriptionRequestJSON(body);
|
|
171
|
+
return ({
|
|
172
|
+
...raw,
|
|
173
|
+
account: KeetaNet.lib.Account.toAccount(raw.account).assertAccount()
|
|
174
|
+
});
|
|
175
|
+
})();
|
|
176
|
+
const verifiedSignature = await Signing.VerifySignedData(request.account, getNotificationDeleteSubscriptionRequestSignable(request), request.signed);
|
|
177
|
+
if (!verifiedSignature) {
|
|
178
|
+
throw (new KeetaAnchorUserError('Invalid signature'));
|
|
179
|
+
}
|
|
180
|
+
const deleteResponse = await deleteSubscriptionHandler(request);
|
|
181
|
+
return ({
|
|
182
|
+
output: JSON.stringify(deleteResponse),
|
|
183
|
+
contentType: 'application/json'
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return (routes);
|
|
188
|
+
}
|
|
189
|
+
async serviceMetadata() {
|
|
190
|
+
const retval = { operations: {} };
|
|
191
|
+
const authentication = {
|
|
192
|
+
method: 'keeta-account',
|
|
193
|
+
type: 'required'
|
|
194
|
+
};
|
|
195
|
+
if (this.notification.registerTarget) {
|
|
196
|
+
retval.operations.registerTarget = { url: (new URL('/api/target', this.url)).toString(), options: { authentication } };
|
|
197
|
+
}
|
|
198
|
+
if (this.notification.listTargets) {
|
|
199
|
+
retval.operations.listTargets = { url: (new URL('/api/targets', this.url)).toString(), options: { authentication } };
|
|
200
|
+
}
|
|
201
|
+
if (this.notification.deleteTarget) {
|
|
202
|
+
retval.operations.deleteTarget = { url: (new URL('/api/delete-target', this.url)).toString(), options: { authentication } };
|
|
203
|
+
}
|
|
204
|
+
if (this.notification.createSubscription) {
|
|
205
|
+
retval.operations.createSubscription = { url: (new URL('/api/subscription', this.url)).toString(), options: { authentication } };
|
|
206
|
+
}
|
|
207
|
+
if (this.notification.listSubscriptions) {
|
|
208
|
+
retval.operations.listSubscriptions = { url: (new URL('/api/subscriptions', this.url)).toString(), options: { authentication } };
|
|
209
|
+
}
|
|
210
|
+
if (this.notification.deleteSubscription) {
|
|
211
|
+
retval.operations.deleteSubscription = { url: (new URL('/api/delete-subscription', this.url)).toString(), options: { authentication } };
|
|
212
|
+
}
|
|
213
|
+
if (this.notification.supportedChannels) {
|
|
214
|
+
retval.supportedChannels = this.notification.supportedChannels;
|
|
215
|
+
}
|
|
216
|
+
if (this.notification.supportedSubscriptions) {
|
|
217
|
+
retval.supportedSubscriptions = this.notification.supportedSubscriptions;
|
|
218
|
+
}
|
|
219
|
+
return (retval);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/services/notification/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeetaNet } from '../../client/index.js';\nimport * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';\nimport type {\n\tKeetaNotificationAnchorRegisterTargetClientRequest,\n\tKeetaNotificationAnchorListTargetsClientRequest,\n\tNotificationTargetWithIDResponse,\n\tKeetaNotificationAnchorDeleteTargetClientRequest,\n\tKeetaNotificationAnchorRegisterTargetRequest,\n\tKeetaNotificationAnchorDeleteTargetRequest,\n\tKeetaNotificationAnchorCreateSubscriptionClientRequest,\n\tKeetaNotificationAnchorDeleteSubscriptionClientRequest,\n\tKeetaNotificationAnchorDeleteSubscriptionRequest,\n\tKeetaNotificationAnchorListSubscriptionsClientRequest,\n\tSubscriptionDetails,\n\tNotificationSubscriptionArguments,\n\tNotificationSubscriptionType,\n\tSupportedChannelConfigurationMetadata,\n\tSubscriptionDetailsJSON\n} from './common.js';\nimport {\n\tgetNotificationRegisterTargetRequestSignable,\n\tassertKeetaNotificationAnchorRegisterTargetRequestJSON,\n\tgetNotificationListTargetsRequestSignable,\n\tassertKeetaNotificationAnchorDeleteTargetRequestJSON,\n\tgetNotificationDeleteTargetRequestSignable,\n\tassertKeetaNotificationAnchorCreateSubscriptionRequestJSON,\n\tgetNotificationCreateSubscriptionRequestSignable,\n\tassertKeetaNotificationAnchorDeleteSubscriptionRequestJSON,\n\tgetNotificationDeleteSubscriptionRequestSignable,\n\tgetNotificationListSubscriptionsRequestSignable\n} from './common.js';\nimport type { ServiceMetadata, ServiceMetadataAuthenticationType } from '../../lib/resolver.js';\nimport type { Routes } from '../../lib/http-server/index.js';\nimport { KeetaAnchorUserError } from '../../lib/error.js';\nimport * as Signing from '../../lib/utils/signing.js';\nimport { parseSignatureFromURL } from '../../lib/http-server/common.js';\n\nexport interface KeetaAnchorNotificationServerConfig extends KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig {\n\thomepage?: string | (() => Promise<string> | string);\n\tnotification: {\n\t\tregisterTarget?: (args: Required<KeetaNotificationAnchorRegisterTargetClientRequest>) => Promise<{ id: string; }>;\n\t\tlistTargets?: (args: Required<KeetaNotificationAnchorListTargetsClientRequest>) => Promise<{ targets: NotificationTargetWithIDResponse[]; }>;\n\t\tdeleteTarget?: (args: Required<KeetaNotificationAnchorDeleteTargetClientRequest>) => Promise<{ ok: boolean; }>;\n\n\t\tcreateSubscription?: (args: Required<KeetaNotificationAnchorCreateSubscriptionClientRequest>) => Promise<{ id: string; }>;\n\t\tlistSubscriptions?: (args: Required<KeetaNotificationAnchorListSubscriptionsClientRequest>) => Promise<{ subscriptions: SubscriptionDetails[]; }>;\n\t\tdeleteSubscription?: (args: Required<KeetaNotificationAnchorDeleteSubscriptionClientRequest>) => Promise<{ ok: boolean; }>;\n\n\t\tsupportedChannels?: SupportedChannelConfigurationMetadata;\n\t\tsupportedSubscriptions?: NotificationSubscriptionType[];\n\t};\n\troutes?: Routes;\n}\n\nexport class KeetaNetNotificationAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<KeetaAnchorNotificationServerConfig> {\n\treadonly homepage: NonNullable<KeetaAnchorNotificationServerConfig['homepage']>;\n\treadonly notification: KeetaAnchorNotificationServerConfig['notification'];\n\treadonly routes: NonNullable<KeetaAnchorNotificationServerConfig['routes']>;\n\n\tconstructor(config: KeetaAnchorNotificationServerConfig) {\n\t\tsuper(config);\n\n\t\tthis.homepage = config.homepage ?? '';\n\t\tthis.notification = config.notification;\n\t\tthis.routes = config.routes ?? {};\n\t}\n\n\tprotected async initRoutes(config: KeetaAnchorNotificationServerConfig): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = { ...this.routes };\n\n\t\tif ('homepage' in config) {\n\t\t\troutes['GET /'] = async function() {\n\t\t\t\tlet homepageData: string;\n\t\t\t\tif (typeof config.homepage === 'string') {\n\t\t\t\t\thomepageData = config.homepage;\n\t\t\t\t} else {\n\t\t\t\t\tif (!config.homepage) {\n\t\t\t\t\t\tthrow(new Error('internal error: No homepage function provided'));\n\t\t\t\t\t}\n\n\t\t\t\t\thomepageData = await config.homepage();\n\t\t\t\t}\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: homepageData,\n\t\t\t\t\tcontentType: 'text/html; charset=utf-8'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\tconst registerTargetHandler = this.notification.registerTarget;\n\t\tif (registerTargetHandler) {\n\t\t\troutes['POST /api/target'] = async (_params, body) => {\n\t\t\t\tconst request: Required<KeetaNotificationAnchorRegisterTargetRequest> = (() => {\n\t\t\t\t\tconst raw = assertKeetaNotificationAnchorRegisterTargetRequestJSON(body);\n\n\t\t\t\t\treturn({\n\t\t\t\t\t\t...raw,\n\t\t\t\t\t\taccount: KeetaNet.lib.Account.toAccount(raw.account)\n\t\t\t\t\t});\n\t\t\t\t})();\n\n\t\t\t\tconst signatureVerified = await Signing.VerifySignedData(\n\t\t\t\t\trequest.account,\n\t\t\t\t\tgetNotificationRegisterTargetRequestSignable(request),\n\t\t\t\t\trequest.signed\n\t\t\t\t);\n\n\t\t\t\tif (!signatureVerified) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t\t\t\t}\n\n\t\t\t\tconst registerResponse = await registerTargetHandler(request);\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: JSON.stringify({\n\t\t\t\t\t\tok: true,\n\t\t\t\t\t\tid: registerResponse.id\n\t\t\t\t\t}),\n\t\t\t\t\tcontentType: 'application/json'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\tconst listTargetsHandler = this.notification.listTargets;\n\t\tif (listTargetsHandler) {\n\t\t\troutes['GET /api/targets'] = async (_ignore_params, _ignore_body, _ignore_headers, url) => {\n\t\t\t\tconst signatureDetails = parseSignatureFromURL(url);\n\n\t\t\t\tif (!signatureDetails.account || !signatureDetails.signedField) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Missing signature parameters in URL'));\n\t\t\t\t}\n\n\t\t\t\tconst verifiedSignature = await Signing.VerifySignedData(\n\t\t\t\t\tsignatureDetails.account,\n\t\t\t\t\tgetNotificationListTargetsRequestSignable(),\n\t\t\t\t\tsignatureDetails.signedField\n\t\t\t\t);\n\n\t\t\t\tif (!verifiedSignature) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t\t\t\t}\n\n\t\t\t\tconst listResponse = await listTargetsHandler({ account: signatureDetails.account });\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: JSON.stringify({\n\t\t\t\t\t\tok: true,\n\t\t\t\t\t\ttargets: listResponse.targets\n\t\t\t\t\t}),\n\t\t\t\t\tcontentType: 'application/json'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\tconst deleteTargetHandler = this.notification.deleteTarget;\n\t\tif (deleteTargetHandler) {\n\t\t\t// XXX:TODO should this be post with body or delete with URL param? Delete with URL param is more RESTful but can be more difficult to call from some clients and doesn't allow for a request body (so all data must be in the URL or signature)\n\t\t\troutes['POST /api/delete-target'] = async (_params, body) => {\n\t\t\t\tconst request: Required<KeetaNotificationAnchorDeleteTargetRequest> = (() => {\n\t\t\t\t\tconst raw = assertKeetaNotificationAnchorDeleteTargetRequestJSON(body);\n\n\t\t\t\t\treturn({\n\t\t\t\t\t\t...raw,\n\t\t\t\t\t\taccount: KeetaNet.lib.Account.toAccount(raw.account)\n\t\t\t\t\t});\n\t\t\t\t})();\n\n\t\t\t\tconst verifiedSignature = await Signing.VerifySignedData(\n\t\t\t\t\trequest.account,\n\t\t\t\t\tgetNotificationDeleteTargetRequestSignable(request),\n\t\t\t\t\trequest.signed\n\t\t\t\t);\n\n\t\t\t\tif (!verifiedSignature) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t\t\t\t}\n\n\t\t\t\tconst deleteResponse = await deleteTargetHandler(request);\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: JSON.stringify(deleteResponse),\n\t\t\t\t\tcontentType: 'application/json'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\tconst createSubscriptionHandler = this.notification.createSubscription;\n\t\tif (createSubscriptionHandler) {\n\t\t\troutes['POST /api/subscription'] = async (_params, body) => {\n\t\t\t\tconst raw = assertKeetaNotificationAnchorCreateSubscriptionRequestJSON(body);\n\t\t\t\tconst account = KeetaNet.lib.Account.fromPublicKeyString(raw.account);\n\n\t\t\t\tlet subscription: NotificationSubscriptionArguments;\n\t\t\t\tif (raw.subscription.type === 'RECEIVE_FUNDS') {\n\t\t\t\t\tsubscription = {\n\t\t\t\t\t\ttype: 'RECEIVE_FUNDS',\n\t\t\t\t\t\ttarget: raw.subscription.target,\n\t\t\t\t\t\t...(raw.subscription.toAddress\n\t\t\t\t\t\t\t? { toAddress: KeetaNet.lib.Account.fromPublicKeyString(raw.subscription.toAddress) }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t...(raw.subscription.locale ? { locale: new Intl.Locale(raw.subscription.locale) } : {})\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tthrow(new KeetaAnchorUserError(`Unsupported subscription type`));\n\t\t\t\t}\n\n\t\t\t\tconst request = { account: account.assertAccount(), subscription, signed: raw.signed };\n\n\t\t\t\tconst signatureVerified = await Signing.VerifySignedData(\n\t\t\t\t\taccount,\n\t\t\t\t\tgetNotificationCreateSubscriptionRequestSignable({ subscription }),\n\t\t\t\t\traw.signed\n\t\t\t\t);\n\n\t\t\t\tif (!signatureVerified) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t\t\t\t}\n\n\t\t\t\tconst createResponse = await createSubscriptionHandler(request);\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: JSON.stringify({ ok: true, id: createResponse.id }),\n\t\t\t\t\tcontentType: 'application/json'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\tconst listSubscriptionsHandler = this.notification.listSubscriptions;\n\t\tif (listSubscriptionsHandler) {\n\t\t\troutes['GET /api/subscriptions'] = async (_ignore_params, _ignore_body, _ignore_headers, url) => {\n\t\t\t\tconst signatureDetails = parseSignatureFromURL(url);\n\n\t\t\t\tif (!signatureDetails.account || !signatureDetails.signedField) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Missing signature parameters in URL'));\n\t\t\t\t}\n\n\t\t\t\tconst verifiedSignature = await Signing.VerifySignedData(\n\t\t\t\t\tsignatureDetails.account,\n\t\t\t\t\tgetNotificationListSubscriptionsRequestSignable(),\n\t\t\t\t\tsignatureDetails.signedField\n\t\t\t\t);\n\n\t\t\t\tif (!verifiedSignature) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t\t\t\t}\n\n\t\t\t\tconst listResponse = await listSubscriptionsHandler({ account: signatureDetails.account });\n\n\t\t\t\tconst subscriptionsJSON: SubscriptionDetailsJSON[] = listResponse.subscriptions.map(function(subscription): SubscriptionDetailsJSON {\n\t\t\t\t\tconst { locale, ...restSubscription } = subscription.subscription;\n\t\t\t\t\treturn({\n\t\t\t\t\t\t...subscription,\n\t\t\t\t\t\tsubscription: {\n\t\t\t\t\t\t\t...KeetaNet.lib.Utils.Conversion.toJSONSerializable(restSubscription),\n\t\t\t\t\t\t\t...(locale ? { locale: locale.toString() } : {})\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: JSON.stringify(KeetaNet.lib.Utils.Conversion.toJSONSerializable({\n\t\t\t\t\t\tok: true,\n\t\t\t\t\t\tsubscriptions: subscriptionsJSON\n\t\t\t\t\t})),\n\t\t\t\t\tcontentType: 'application/json'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\tconst deleteSubscriptionHandler = this.notification.deleteSubscription;\n\t\tif (deleteSubscriptionHandler) {\n\t\t\troutes['POST /api/delete-subscription'] = async (_params, body) => {\n\t\t\t\tconst request: Required<KeetaNotificationAnchorDeleteSubscriptionRequest> = (() => {\n\t\t\t\t\tconst raw = assertKeetaNotificationAnchorDeleteSubscriptionRequestJSON(body);\n\n\t\t\t\t\treturn({\n\t\t\t\t\t\t...raw,\n\t\t\t\t\t\taccount: KeetaNet.lib.Account.toAccount(raw.account).assertAccount()\n\t\t\t\t\t});\n\t\t\t\t})();\n\n\t\t\t\tconst verifiedSignature = await Signing.VerifySignedData(\n\t\t\t\t\trequest.account,\n\t\t\t\t\tgetNotificationDeleteSubscriptionRequestSignable(request),\n\t\t\t\t\trequest.signed\n\t\t\t\t);\n\n\t\t\t\tif (!verifiedSignature) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t\t\t\t}\n\n\t\t\t\tconst deleteResponse = await deleteSubscriptionHandler(request);\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: JSON.stringify(deleteResponse),\n\t\t\t\t\tcontentType: 'application/json'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\treturn(routes);\n\t}\n\n\tasync serviceMetadata(): Promise<NonNullable<ServiceMetadata['services']['notification']>[string]> {\n\t\tconst retval: NonNullable<ServiceMetadata['services']['notification']>[string] = { operations: {}};\n\n\t\tconst authentication: ServiceMetadataAuthenticationType = {\n\t\t\tmethod: 'keeta-account',\n\t\t\ttype: 'required'\n\t\t}\n\n\t\tif (this.notification.registerTarget) {\n\t\t\tretval.operations.registerTarget = { url: (new URL('/api/target', this.url)).toString(), options: { authentication }};\n\t\t}\n\n\t\tif (this.notification.listTargets) {\n\t\t\tretval.operations.listTargets = { url: (new URL('/api/targets', this.url)).toString(), options: { authentication }};\n\t\t}\n\n\t\tif (this.notification.deleteTarget) {\n\t\t\tretval.operations.deleteTarget = { url: (new URL('/api/delete-target', this.url)).toString(), options: { authentication }};\n\t\t}\n\n\t\tif (this.notification.createSubscription) {\n\t\t\tretval.operations.createSubscription = { url: (new URL('/api/subscription', this.url)).toString(), options: { authentication }};\n\t\t}\n\n\t\tif (this.notification.listSubscriptions) {\n\t\t\tretval.operations.listSubscriptions = { url: (new URL('/api/subscriptions', this.url)).toString(), options: { authentication }};\n\t\t}\n\n\t\tif (this.notification.deleteSubscription) {\n\t\t\tretval.operations.deleteSubscription = { url: (new URL('/api/delete-subscription', this.url)).toString(), options: { authentication }};\n\t\t}\n\n\t\tif (this.notification.supportedChannels) {\n\t\t\tretval.supportedChannels = this.notification.supportedChannels;\n\t\t}\n\n\t\tif (this.notification.supportedSubscriptions) {\n\t\t\tretval.supportedSubscriptions = this.notification.supportedSubscriptions;\n\t\t}\n\n\t\treturn(retval);\n\t}\n}\n"]}
|