@stellar/typescript-wallet-sdk 1.5.0 → 1.6.0-beta.1719867067726
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/CHANGELOG.MD +11 -1
- package/lib/bundle.js +7354 -3358
- package/lib/bundle.js.map +1 -1
- package/lib/bundle_browser.js +1117 -11
- package/lib/bundle_browser.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/walletSdk/Exceptions/index.d.ts +15 -0
- package/lib/walletSdk/Types/anchor.d.ts +5 -1
- package/lib/walletSdk/Types/index.d.ts +1 -0
- package/lib/walletSdk/Types/sep7.d.ts +15 -0
- package/lib/walletSdk/Uri/Sep7Base.d.ts +187 -0
- package/lib/walletSdk/Uri/Sep7Pay.d.ts +121 -0
- package/lib/walletSdk/Uri/Sep7Tx.d.ts +133 -0
- package/lib/walletSdk/Uri/index.d.ts +4 -0
- package/lib/walletSdk/Uri/sep7Parser.d.ts +60 -0
- package/lib/walletSdk/Utils/index.d.ts +2 -1
- package/package.json +3 -3
- package/src/index.ts +9 -0
- package/src/walletSdk/Auth/WalletSigner.ts +3 -3
- package/src/walletSdk/Customer/index.ts +7 -7
- package/src/walletSdk/Exceptions/index.ts +38 -1
- package/src/walletSdk/Horizon/Account.ts +2 -1
- package/src/walletSdk/Types/anchor.ts +4 -0
- package/src/walletSdk/Types/index.ts +1 -0
- package/src/walletSdk/Types/sep7.ts +19 -0
- package/src/walletSdk/Uri/Sep7Base.ts +311 -0
- package/src/walletSdk/Uri/Sep7Pay.ts +169 -0
- package/src/walletSdk/Uri/Sep7Tx.ts +193 -0
- package/src/walletSdk/Uri/index.ts +9 -0
- package/src/walletSdk/Uri/sep7Parser.ts +220 -0
- package/src/walletSdk/Utils/index.ts +2 -1
- package/src/walletSdk/Watcher/index.ts +3 -1
- package/test/customer.test.ts +7 -7
- package/test/integration/anchorplatform.test.ts +2 -2
- package/test/sep7.test.ts +825 -0
|
@@ -17,10 +17,10 @@ import {
|
|
|
17
17
|
* @class
|
|
18
18
|
*/
|
|
19
19
|
export class Sep12 {
|
|
20
|
-
private authToken;
|
|
21
|
-
private baseUrl;
|
|
22
|
-
private httpClient;
|
|
23
|
-
private headers;
|
|
20
|
+
private authToken: AuthToken;
|
|
21
|
+
private baseUrl: string;
|
|
22
|
+
private httpClient: AxiosInstance;
|
|
23
|
+
private headers: { [key: string]: string };
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Creates a new instance of the Sep12 class.
|
|
@@ -64,7 +64,7 @@ export class Sep12 {
|
|
|
64
64
|
if (!resp.data.id) {
|
|
65
65
|
throw new CustomerNotFoundError(params);
|
|
66
66
|
}
|
|
67
|
-
return resp;
|
|
67
|
+
return resp.data;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
@@ -104,7 +104,7 @@ export class Sep12 {
|
|
|
104
104
|
: this.headers,
|
|
105
105
|
},
|
|
106
106
|
);
|
|
107
|
-
return resp;
|
|
107
|
+
return resp.data;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
/**
|
|
@@ -154,7 +154,7 @@ export class Sep12 {
|
|
|
154
154
|
: this.headers,
|
|
155
155
|
},
|
|
156
156
|
);
|
|
157
|
-
return resp;
|
|
157
|
+
return resp.data;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
@@ -306,6 +306,20 @@ export class InvalidJsonError extends Error {
|
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
export class SigningKeypairMissingSecretError extends Error {
|
|
310
|
+
constructor() {
|
|
311
|
+
super("This keypair doesn't have a secret key and can't sign");
|
|
312
|
+
Object.setPrototypeOf(this, SigningKeypairMissingSecretError.prototype);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export class DefaultSignerDomainAccountError extends Error {
|
|
317
|
+
constructor() {
|
|
318
|
+
super("The DefaultSigner can't sign transactions with domain account");
|
|
319
|
+
Object.setPrototypeOf(this, DefaultSignerDomainAccountError.prototype);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
309
323
|
export class AuthHeaderSigningKeypairRequiredError extends Error {
|
|
310
324
|
constructor() {
|
|
311
325
|
super("Must be SigningKeypair to sign auth header");
|
|
@@ -319,8 +333,31 @@ export class AuthHeaderSigningKeypairRequiredError extends Error {
|
|
|
319
333
|
export class AuthHeaderClientDomainRequiredError extends Error {
|
|
320
334
|
constructor() {
|
|
321
335
|
super(
|
|
322
|
-
"This class should only be used for remote signing. For local signing use DefaultAuthHeaderSigner
|
|
336
|
+
"This class should only be used for remote signing. For local signing use DefaultAuthHeaderSigner",
|
|
323
337
|
);
|
|
324
338
|
Object.setPrototypeOf(this, AuthHeaderClientDomainRequiredError.prototype);
|
|
325
339
|
}
|
|
326
340
|
}
|
|
341
|
+
|
|
342
|
+
export class Sep7InvalidUriError extends Error {
|
|
343
|
+
constructor(reason: string) {
|
|
344
|
+
super(`Invalid Stellar Sep-7 URI, reason: ${reason}`);
|
|
345
|
+
Object.setPrototypeOf(this, Sep7InvalidUriError.prototype);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export class Sep7LongMsgError extends Error {
|
|
350
|
+
constructor(msgMaxLength: number) {
|
|
351
|
+
super(`'msg' should be no longer than ${msgMaxLength} characters`);
|
|
352
|
+
Object.setPrototypeOf(this, Sep7LongMsgError.prototype);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export class Sep7UriTypeNotSupportedError extends Error {
|
|
357
|
+
constructor(type: string) {
|
|
358
|
+
super(
|
|
359
|
+
`Stellar Sep-7 URI operation type '${type}' is not currently supported`,
|
|
360
|
+
);
|
|
361
|
+
Object.setPrototypeOf(this, Sep7UriTypeNotSupportedError.prototype);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Keypair, Transaction, FeeBumpTransaction } from "@stellar/stellar-sdk";
|
|
2
|
+
import { SigningKeypairMissingSecretError } from "../Exceptions";
|
|
2
3
|
|
|
3
4
|
export class AccountKeypair {
|
|
4
5
|
keypair: Keypair;
|
|
@@ -28,7 +29,7 @@ export class PublicKeypair extends AccountKeypair {
|
|
|
28
29
|
export class SigningKeypair extends AccountKeypair {
|
|
29
30
|
constructor(keypair: Keypair) {
|
|
30
31
|
if (!keypair.canSign()) {
|
|
31
|
-
throw new
|
|
32
|
+
throw new SigningKeypairMissingSecretError();
|
|
32
33
|
}
|
|
33
34
|
super(keypair);
|
|
34
35
|
}
|
|
@@ -192,4 +192,8 @@ export enum TransactionStatus {
|
|
|
192
192
|
|
|
193
193
|
/** Catch-all for any error not enumerated above. */
|
|
194
194
|
error = "error",
|
|
195
|
+
/** deposit/withdrawal is currently on hold for additional checks after receiving user's funds.
|
|
196
|
+
* Anchor may use this status to indicate to the user that transaction is being reviewed (for example,
|
|
197
|
+
* for compliance reasons). Once this status cleared, transaction should follow the regular flow */
|
|
198
|
+
on_hold = "on_hold",
|
|
195
199
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const WEB_STELLAR_SCHEME = "web+stellar:";
|
|
2
|
+
|
|
3
|
+
export enum Sep7OperationType {
|
|
4
|
+
tx = "tx",
|
|
5
|
+
pay = "pay",
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const URI_MSG_MAX_LENGTH = 300;
|
|
9
|
+
|
|
10
|
+
export type Sep7Replacement = {
|
|
11
|
+
id: string;
|
|
12
|
+
path: string;
|
|
13
|
+
hint: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type IsValidSep7UriResult = {
|
|
17
|
+
result: boolean;
|
|
18
|
+
reason?: string;
|
|
19
|
+
};
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { Keypair, Networks, StellarToml } from "@stellar/stellar-sdk";
|
|
2
|
+
import { Sep7OperationType, URI_MSG_MAX_LENGTH } from "../Types";
|
|
3
|
+
import { Sep7LongMsgError } from "../Exceptions";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A base abstract class containing common functions that should be used by both
|
|
7
|
+
* Sep7Tx and Sep7Pay classes for parsing or constructing SEP-0007 Stellar URIs.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md#specification
|
|
10
|
+
*/
|
|
11
|
+
export abstract class Sep7Base {
|
|
12
|
+
protected uri: URL;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new instance of the Sep7 class.
|
|
16
|
+
*
|
|
17
|
+
* @constructor
|
|
18
|
+
* @param {URL | string} uri - uri to initialize the Sep7 instance.
|
|
19
|
+
*/
|
|
20
|
+
constructor(uri: URL | string) {
|
|
21
|
+
this.uri = new URL(uri.toString());
|
|
22
|
+
|
|
23
|
+
if (this.msg?.length > URI_MSG_MAX_LENGTH) {
|
|
24
|
+
throw new Sep7LongMsgError(URI_MSG_MAX_LENGTH);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Should return a deep clone of this instance.
|
|
30
|
+
*
|
|
31
|
+
* @returns {Sep7Base} a deep clone of the Sep7Base extended instance.
|
|
32
|
+
*/
|
|
33
|
+
abstract clone(): Sep7Base;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns a stringfied URL-decoded version of the 'uri' object.
|
|
37
|
+
*
|
|
38
|
+
* @returns {string} the uri decoded string value.
|
|
39
|
+
*/
|
|
40
|
+
toString(): string {
|
|
41
|
+
return this.uri.toString();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns uri's pathname as the operation type.
|
|
46
|
+
*
|
|
47
|
+
* @returns {Sep7OperationType} the operation type, either "tx" or "pay".
|
|
48
|
+
*/
|
|
49
|
+
get operationType(): Sep7OperationType {
|
|
50
|
+
return this.uri.pathname as Sep7OperationType;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Returns a URL-decoded version of the uri 'callback' param without
|
|
55
|
+
* the 'url:' prefix.
|
|
56
|
+
*
|
|
57
|
+
* The URI handler should send the signed XDR to this callback url, if this
|
|
58
|
+
* value is omitted then the URI handler should submit it to the network.
|
|
59
|
+
*
|
|
60
|
+
* @returns {string | undefined} URL-decoded 'callback' param if present.
|
|
61
|
+
*/
|
|
62
|
+
get callback(): string | undefined {
|
|
63
|
+
const callback = this.getParam("callback");
|
|
64
|
+
|
|
65
|
+
if (callback?.startsWith("url:")) {
|
|
66
|
+
return callback.replace("url:", "");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return callback;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Sets and URL-encodes the uri 'callback' param, appends the 'url:'
|
|
74
|
+
* prefix to it if not yet present.
|
|
75
|
+
*
|
|
76
|
+
* Deletes the uri 'callback' param if set as 'undefined'.
|
|
77
|
+
*
|
|
78
|
+
* The URI handler should send the signed XDR to this callback url, if this
|
|
79
|
+
* value is omitted then the URI handler should submit it to the network.
|
|
80
|
+
*
|
|
81
|
+
* @param {string | undefined} callback the uri 'callback' param to be set.
|
|
82
|
+
*/
|
|
83
|
+
set callback(callback: string | undefined) {
|
|
84
|
+
if (!callback) {
|
|
85
|
+
this.setParam("callback", undefined);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (callback.startsWith("url:")) {
|
|
90
|
+
this.setParam("callback", callback);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.setParam("callback", `url:${callback}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Returns a URL-decoded version of the uri 'msg' param.
|
|
99
|
+
*
|
|
100
|
+
* This message should indicate any additional information that the website
|
|
101
|
+
* or application wants to show the user in her wallet.
|
|
102
|
+
*
|
|
103
|
+
* @returns {string | undefined} URL-decoded 'msg' param if present.
|
|
104
|
+
*/
|
|
105
|
+
get msg(): string | undefined {
|
|
106
|
+
return this.getParam("msg");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Sets and URL-encodes the uri 'msg' param, the 'msg' param can't
|
|
111
|
+
* be larger than 300 characters.
|
|
112
|
+
*
|
|
113
|
+
* Deletes the uri 'msg' param if set as 'undefined'.
|
|
114
|
+
*
|
|
115
|
+
* This message should indicate any additional information that the website
|
|
116
|
+
* or application wants to show the user in her wallet.
|
|
117
|
+
*
|
|
118
|
+
* @param {string | undefined} msg the uri 'msg' param to be set.
|
|
119
|
+
* @throws {Sep7LongMsgError} if 'msg' length is bigger than 300.
|
|
120
|
+
*/
|
|
121
|
+
set msg(msg: string | undefined) {
|
|
122
|
+
if (msg?.length > URI_MSG_MAX_LENGTH) {
|
|
123
|
+
throw new Sep7LongMsgError(URI_MSG_MAX_LENGTH);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.setParam("msg", msg);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Returns uri 'network_passphrase' param, if not present returns
|
|
131
|
+
* the PUBLIC Network value by default: 'Public Global Stellar Network ; September 2015'.
|
|
132
|
+
*
|
|
133
|
+
* @returns {Networks} the Stellar network passphrase considered for this uri.
|
|
134
|
+
*/
|
|
135
|
+
get networkPassphrase(): Networks {
|
|
136
|
+
return (this.getParam("network_passphrase") ?? Networks.PUBLIC) as Networks;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Sets the uri 'network_passphrase' param.
|
|
141
|
+
*
|
|
142
|
+
* Deletes the uri 'network_passphrase' param if set as 'undefined'.
|
|
143
|
+
*
|
|
144
|
+
* Only need to set it if this transaction is for a network other than
|
|
145
|
+
* the public network.
|
|
146
|
+
*
|
|
147
|
+
* @param {Networks | undefined} networkPassphrase the uri 'network_passphrase'
|
|
148
|
+
* param to be set.
|
|
149
|
+
*/
|
|
150
|
+
set networkPassphrase(networkPassphrase: Networks | undefined) {
|
|
151
|
+
this.setParam("network_passphrase", networkPassphrase);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Returns a URL-decoded version of the uri 'origin_domain' param.
|
|
156
|
+
*
|
|
157
|
+
* This should be a fully qualified domain name that specifies the originating
|
|
158
|
+
* domain of the URI request.
|
|
159
|
+
*
|
|
160
|
+
* @returns {string | undefined} URL-decoded 'origin_domain' param if present.
|
|
161
|
+
*/
|
|
162
|
+
get originDomain(): string | undefined {
|
|
163
|
+
return this.getParam("origin_domain");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Sets and URL-encodes the uri 'origin_domain' param.
|
|
168
|
+
*
|
|
169
|
+
* Deletes the uri 'origin_domain' param if set as 'undefined'.
|
|
170
|
+
*
|
|
171
|
+
* This should be a fully qualified domain name that specifies the originating
|
|
172
|
+
* domain of the URI request.
|
|
173
|
+
*
|
|
174
|
+
* @param {string | undefined} originDomain the uri 'origin_domain' param
|
|
175
|
+
* to be set.
|
|
176
|
+
*/
|
|
177
|
+
set originDomain(originDomain: string | undefined) {
|
|
178
|
+
this.setParam("origin_domain", originDomain);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Returns a URL-decoded version of the uri 'signature' param.
|
|
183
|
+
*
|
|
184
|
+
* This should be a signature of the hash of the URI request (excluding the
|
|
185
|
+
* 'signature' field and value itself).
|
|
186
|
+
*
|
|
187
|
+
* Wallets should use the URI_REQUEST_SIGNING_KEY specified in the
|
|
188
|
+
* origin_domain's stellar.toml file to validate this signature.
|
|
189
|
+
* If the verification fails, wallets must alert the user.
|
|
190
|
+
*
|
|
191
|
+
* @returns {string | undefined} URL-decoded 'signature' param if present.
|
|
192
|
+
*/
|
|
193
|
+
get signature(): string | undefined {
|
|
194
|
+
return this.getParam("signature");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Signs the URI with the given keypair, which means it sets the 'signature' param.
|
|
199
|
+
*
|
|
200
|
+
* This should be the last step done before generating the URI string,
|
|
201
|
+
* otherwise the signature will be invalid for the URI.
|
|
202
|
+
*
|
|
203
|
+
* @see https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md#request-signing
|
|
204
|
+
*
|
|
205
|
+
* @param {Keypair} keypair The keypair (including secret key), used to sign the request.
|
|
206
|
+
* This should be the keypair found in the URI_REQUEST_SIGNING_KEY field of the
|
|
207
|
+
* origin_domains' stellar.toml.
|
|
208
|
+
*
|
|
209
|
+
* @returns {string} the generated 'signature' param.
|
|
210
|
+
*/
|
|
211
|
+
addSignature(keypair: Keypair): string {
|
|
212
|
+
const payload = this.createSignaturePayload();
|
|
213
|
+
const signature = keypair.sign(payload).toString("base64");
|
|
214
|
+
this.setParam("signature", signature);
|
|
215
|
+
return signature;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Verifies that the signature added to the URI is valid.
|
|
220
|
+
*
|
|
221
|
+
* @see https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md#request-signing
|
|
222
|
+
*
|
|
223
|
+
* @returns {Promise<boolean>} returns 'true' if the signature is valid for
|
|
224
|
+
* the current URI and origin_domain. Returns 'false' if signature verification
|
|
225
|
+
* fails, or if there is a problem looking up the stellar.toml associated with
|
|
226
|
+
* the origin_domain.
|
|
227
|
+
*/
|
|
228
|
+
async verifySignature(): Promise<boolean> {
|
|
229
|
+
const originDomain = this.originDomain;
|
|
230
|
+
const signature = this.signature;
|
|
231
|
+
|
|
232
|
+
// we can fail fast if neither of them are set since we can't verify without both
|
|
233
|
+
if (!originDomain || !signature) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const toml = await StellarToml.Resolver.resolve(originDomain);
|
|
239
|
+
const signingKey = toml.URI_REQUEST_SIGNING_KEY;
|
|
240
|
+
|
|
241
|
+
if (!signingKey) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
const keypair = Keypair.fromPublicKey(signingKey);
|
|
245
|
+
const payload = this.createSignaturePayload();
|
|
246
|
+
return keypair.verify(payload, Buffer.from(signature, "base64"));
|
|
247
|
+
} catch (e) {
|
|
248
|
+
// if something fails we assume signature verification failed
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Finds the uri param related to the inputted 'key', if any, and returns
|
|
255
|
+
* a URL-decoded version of it. Returns 'undefined' if key param not found.
|
|
256
|
+
*
|
|
257
|
+
* @param {string} key the uri param key.
|
|
258
|
+
*
|
|
259
|
+
* @returns {string | undefined} URL-decoded value of the uri param if found.
|
|
260
|
+
*/
|
|
261
|
+
protected getParam(key: string): string | undefined {
|
|
262
|
+
// the searchParams.get() function automatically applies URL dencoding.
|
|
263
|
+
return this.uri.searchParams.get(key) || undefined;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Sets and URL-encodes a 'key=value' uri param.
|
|
268
|
+
*
|
|
269
|
+
* Deletes the uri param if 'value' set as 'undefined'.
|
|
270
|
+
*
|
|
271
|
+
* @param {string} key the uri param key.
|
|
272
|
+
* @param {string | undefined} value the uri param value to be set.
|
|
273
|
+
*/
|
|
274
|
+
protected setParam(key: string, value: string | undefined) {
|
|
275
|
+
if (!value) {
|
|
276
|
+
this.uri.searchParams.delete(key);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// the searchParams.set() function automatically applies URL encoding.
|
|
281
|
+
this.uri.searchParams.set(key, value);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Converts the URI request into the payload that will be signed by
|
|
286
|
+
* the 'addSignature' method.
|
|
287
|
+
*
|
|
288
|
+
* @see https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md#request-signing
|
|
289
|
+
*
|
|
290
|
+
* @returns {Buffer} array of bytes to be signed with given keypair on
|
|
291
|
+
* the 'addSignature' method.
|
|
292
|
+
*/
|
|
293
|
+
private createSignaturePayload(): Buffer {
|
|
294
|
+
let data = this.toString();
|
|
295
|
+
|
|
296
|
+
const signature = this.signature;
|
|
297
|
+
if (signature) {
|
|
298
|
+
// the payload must be created without the signature on it
|
|
299
|
+
data = data.replace(`&signature=${encodeURIComponent(signature)}`, "");
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// The first 35 bytes of the payload are all 0, the 36th byte is 4.
|
|
303
|
+
// Then we concatenate the URI request with the prefix 'stellar.sep.7 - URI Scheme'
|
|
304
|
+
// (no delimiter) and convert that to bytes to give use the final payload to be signed.
|
|
305
|
+
return Buffer.concat([
|
|
306
|
+
Buffer.alloc(35, 0),
|
|
307
|
+
Buffer.alloc(1, 4),
|
|
308
|
+
Buffer.from(`stellar.sep.7 - URI Scheme${data}`),
|
|
309
|
+
]);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { MemoType } from "@stellar/stellar-sdk";
|
|
2
|
+
import { Sep7Base } from "../Uri";
|
|
3
|
+
import { Sep7OperationType, WEB_STELLAR_SCHEME } from "../Types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The Sep-7 'pay' operation represents a request to pay a specific address
|
|
7
|
+
* with a specific asset, regardless of the source asset used by the payer.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md#operation-pay
|
|
10
|
+
*/
|
|
11
|
+
export class Sep7Pay extends Sep7Base {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a Sep7Pay instance with given destination.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} destination a valid Stellar address to receive the payment.
|
|
16
|
+
*
|
|
17
|
+
* @returns {Sep7Pay} the Sep7Pay instance.
|
|
18
|
+
*/
|
|
19
|
+
static forDestination(destination: string): Sep7Pay {
|
|
20
|
+
const uri = new Sep7Pay();
|
|
21
|
+
uri.destination = destination;
|
|
22
|
+
return uri;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new instance of the Sep7Pay class.
|
|
27
|
+
*
|
|
28
|
+
* @constructor
|
|
29
|
+
* @param {URL | string} [uri] - uri to initialize the Sep7 instance.
|
|
30
|
+
*/
|
|
31
|
+
constructor(uri?: URL | string) {
|
|
32
|
+
super(uri ?? new URL(`${WEB_STELLAR_SCHEME}${Sep7OperationType.pay}`));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns a deep clone of this instance.
|
|
37
|
+
*
|
|
38
|
+
* @returns {Sep7Pay} a deep clone of this Sep7Pay instance.
|
|
39
|
+
*/
|
|
40
|
+
clone(): Sep7Pay {
|
|
41
|
+
return new Sep7Pay(this.uri);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gets the destination of the payment request, which should be a valid
|
|
46
|
+
* Stellar address.
|
|
47
|
+
*
|
|
48
|
+
* @returns {string | undefined} the 'destination' uri param if present.
|
|
49
|
+
*/
|
|
50
|
+
get destination(): string | undefined {
|
|
51
|
+
return this.getParam("destination");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Sets the destination of the payment request, which should be a valid
|
|
56
|
+
* Stellar address.
|
|
57
|
+
*
|
|
58
|
+
* Deletes the uri 'destination' param if set as 'undefined'.
|
|
59
|
+
*
|
|
60
|
+
* @param {string | undefined} destination the uri 'destination' param to be set.
|
|
61
|
+
*/
|
|
62
|
+
set destination(destination: string | undefined) {
|
|
63
|
+
this.setParam("destination", destination);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gets the amount that destination should receive.
|
|
68
|
+
*
|
|
69
|
+
* @returns {string | undefined} the 'amount' uri param if present.
|
|
70
|
+
*/
|
|
71
|
+
get amount(): string | undefined {
|
|
72
|
+
return this.getParam("amount");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Sets the amount that destination should receive.
|
|
77
|
+
*
|
|
78
|
+
* Deletes the uri 'amount' param if set as 'undefined'.
|
|
79
|
+
*
|
|
80
|
+
* @param {string | undefined} amount the uri 'amount' param to be set.
|
|
81
|
+
*/
|
|
82
|
+
set amount(amount: string | undefined) {
|
|
83
|
+
this.setParam("amount", amount);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Gets the code from the asset that destination should receive.
|
|
88
|
+
*
|
|
89
|
+
* @returns {string | undefined} the 'asset_code' uri param if present.
|
|
90
|
+
*/
|
|
91
|
+
get assetCode(): string | undefined {
|
|
92
|
+
return this.getParam("asset_code");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Sets the code from the asset that destination should receive.
|
|
97
|
+
*
|
|
98
|
+
* Deletes the uri 'asset_code' param if set as 'undefined'.
|
|
99
|
+
*
|
|
100
|
+
* @param {string | undefined} assetCode the uri 'asset_code' param to be set.
|
|
101
|
+
*/
|
|
102
|
+
set assetCode(assetCode: string | undefined) {
|
|
103
|
+
this.setParam("asset_code", assetCode);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets the account ID of asset issuer the destination should receive.
|
|
108
|
+
*
|
|
109
|
+
* @returns {string | undefined} the 'asset_issuer' uri param if present.
|
|
110
|
+
*/
|
|
111
|
+
get assetIssuer(): string | undefined {
|
|
112
|
+
return this.getParam("asset_issuer");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Sets the account ID of asset issuer the destination should receive.
|
|
117
|
+
*
|
|
118
|
+
* Deletes the uri 'asset_issuer' param if set as 'undefined'.
|
|
119
|
+
*
|
|
120
|
+
* @param {string | undefined} assetIssuer the uri 'asset_issuer' param to be set.
|
|
121
|
+
*/
|
|
122
|
+
set assetIssuer(assetIssuer: string | undefined) {
|
|
123
|
+
this.setParam("asset_issuer", assetIssuer);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Gets the memo to be included in the payment / path payment.
|
|
128
|
+
* Memos of type MEMO_HASH and MEMO_RETURN should be base64-decoded
|
|
129
|
+
* after returned from this function.
|
|
130
|
+
*
|
|
131
|
+
* @returns {string | undefined} the 'memo' uri param if present.
|
|
132
|
+
*/
|
|
133
|
+
get memo(): string | undefined {
|
|
134
|
+
return this.getParam("memo");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Sets the memo to be included in the payment / path payment.
|
|
139
|
+
* Memos of type MEMO_HASH and MEMO_RETURN should be base64-encoded
|
|
140
|
+
* prior to being passed on this function.
|
|
141
|
+
*
|
|
142
|
+
* Deletes the uri 'memo' param if set as 'undefined'.
|
|
143
|
+
*
|
|
144
|
+
* @param {string | undefined} memo the uri 'memo' param to be set.
|
|
145
|
+
*/
|
|
146
|
+
set memo(memo: string | undefined) {
|
|
147
|
+
this.setParam("memo", memo);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Gets the type of the memo.
|
|
152
|
+
*
|
|
153
|
+
* @returns {MemoType | undefined} the 'memo_type' uri param if present.
|
|
154
|
+
*/
|
|
155
|
+
get memoType(): MemoType | undefined {
|
|
156
|
+
return this.getParam("memo_type") as MemoType | undefined;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Sets the type of the memo.
|
|
161
|
+
*
|
|
162
|
+
* Deletes the uri 'memo_type' param if set as 'undefined'.
|
|
163
|
+
*
|
|
164
|
+
* @param {MemoType | undefined} memoType the uri 'memo_type' param to be set.
|
|
165
|
+
*/
|
|
166
|
+
set memoType(memoType: MemoType | undefined) {
|
|
167
|
+
this.setParam("memo_type", memoType);
|
|
168
|
+
}
|
|
169
|
+
}
|