@ledgerhq/coin-framework 0.7.1-hotfix.0 → 0.8.0-hotfix.1
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +6 -0
- package/lib/account/accountId.d.ts +2 -0
- package/lib/account/accountId.d.ts.map +1 -1
- package/lib/account/accountId.js +21 -3
- package/lib/account/accountId.js.map +1 -1
- package/lib/account/accountId.unit.test.d.ts +2 -0
- package/lib/account/accountId.unit.test.d.ts.map +1 -0
- package/lib/account/accountId.unit.test.js +54 -0
- package/lib/account/accountId.unit.test.js.map +1 -0
- package/lib-es/account/accountId.d.ts +2 -0
- package/lib-es/account/accountId.d.ts.map +1 -1
- package/lib-es/account/accountId.js +18 -2
- package/lib-es/account/accountId.js.map +1 -1
- package/lib-es/account/accountId.unit.test.d.ts +2 -0
- package/lib-es/account/accountId.unit.test.d.ts.map +1 -0
- package/lib-es/account/accountId.unit.test.js +52 -0
- package/lib-es/account/accountId.unit.test.js.map +1 -0
- package/package.json +1 -1
- package/src/account/accountId.ts +22 -2
- package/src/account/accountId.unit.test.ts +73 -0
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ledgerhq/coin-framework
|
|
2
2
|
|
|
3
|
+
## 0.8.0-hotfix.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#5042](https://github.com/LedgerHQ/ledger-live/pull/5042) [`3b4f7501cc`](https://github.com/LedgerHQ/ledger-live/commit/3b4f7501cc5f09be94a2994f20f9998898682975) Thanks [@lambertkevin](https://github.com/lambertkevin)! - Modify token ids encoding in `TokenAccounts` ids which could contain characters preventing the correct "deserialization" of those ids.
|
|
8
|
+
|
|
3
9
|
## 0.7.1-hotfix.0
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AccountIdParams, DerivationMode } from "@ledgerhq/types-live";
|
|
2
2
|
import type { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
3
|
+
export declare function safeEncodeTokenId(tokenId: string): string;
|
|
4
|
+
export declare function safeDecodeTokenId(encodedTokenId: string): string;
|
|
3
5
|
export declare function encodeAccountId({ type, version, currencyId, xpubOrAddress, derivationMode, }: AccountIdParams): string;
|
|
4
6
|
export declare function encodeTokenAccountId(accountId: string, token: TokenCurrency): string;
|
|
5
7
|
export declare function decodeTokenAccountId(id: string): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountId.d.ts","sourceRoot":"","sources":["../../src/account/accountId.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAOlF,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,UAAU,EACV,aAAa,EACb,cAAc,GACf,EAAE,eAAe,GAAG,MAAM,CAQ1B;AACD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAEpF;AACD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CACzC,CAYA;AACD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAYlE;AAGD,wBAAgB,aAAa,CAAC,EAC5B,cAAc,EACd,cAAc,EACd,QAAQ,GACT,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,cAAc,CAAC;CAC1B,GAAG,MAAM,CAET;AACD,eAAO,MAAM,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAS7E,CAAC"}
|
|
1
|
+
{"version":3,"file":"accountId.d.ts","sourceRoot":"","sources":["../../src/account/accountId.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAOlF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAShE;AAED,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,UAAU,EACV,aAAa,EACb,cAAc,GACf,EAAE,eAAe,GAAG,MAAM,CAQ1B;AACD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAEpF;AACD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CACzC,CAYA;AACD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAYlE;AAGD,wBAAgB,aAAa,CAAC,EAC5B,cAAc,EACd,cAAc,EACd,QAAQ,GACT,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,cAAc,CAAC;CAC1B,GAAG,MAAM,CAET;AACD,eAAO,MAAM,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAS7E,CAAC"}
|
package/lib/account/accountId.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.inferFamilyFromAccountId = exports.getWalletName = exports.decodeAccountId = exports.decodeTokenAccountId = exports.encodeTokenAccountId = exports.encodeAccountId = void 0;
|
|
6
|
+
exports.inferFamilyFromAccountId = exports.getWalletName = exports.decodeAccountId = exports.decodeTokenAccountId = exports.encodeTokenAccountId = exports.encodeAccountId = exports.safeDecodeTokenId = exports.safeEncodeTokenId = void 0;
|
|
7
7
|
const memoize_1 = __importDefault(require("lodash/memoize"));
|
|
8
8
|
const invariant_1 = __importDefault(require("invariant"));
|
|
9
9
|
const derivation_1 = require("../derivation");
|
|
@@ -13,17 +13,35 @@ function ensureNoColon(value, ctx) {
|
|
|
13
13
|
(0, invariant_1.default)(!value.includes(":"), "AccountId '%s' component must not use colon", ctx);
|
|
14
14
|
return value;
|
|
15
15
|
}
|
|
16
|
+
function safeEncodeTokenId(tokenId) {
|
|
17
|
+
if (!tokenId)
|
|
18
|
+
return "";
|
|
19
|
+
const URIEncoded = encodeURIComponent(tokenId);
|
|
20
|
+
const dashUnderscoreSafe = URIEncoded.replace(/-/g, "~!dash!~").replace(/_/g, "~!underscore!~");
|
|
21
|
+
return dashUnderscoreSafe;
|
|
22
|
+
}
|
|
23
|
+
exports.safeEncodeTokenId = safeEncodeTokenId;
|
|
24
|
+
function safeDecodeTokenId(encodedTokenId) {
|
|
25
|
+
if (!encodedTokenId)
|
|
26
|
+
return "";
|
|
27
|
+
const dashUnderscoreUnsafe = encodedTokenId
|
|
28
|
+
.replace(/~!dash!~/g, "-")
|
|
29
|
+
.replace(/~!underscore!~/g, "_");
|
|
30
|
+
const decodedURIComponent = decodeURIComponent(dashUnderscoreUnsafe);
|
|
31
|
+
return decodedURIComponent;
|
|
32
|
+
}
|
|
33
|
+
exports.safeDecodeTokenId = safeDecodeTokenId;
|
|
16
34
|
function encodeAccountId({ type, version, currencyId, xpubOrAddress, derivationMode, }) {
|
|
17
35
|
return `${ensureNoColon(type, "type")}:${ensureNoColon(version, "version")}:${ensureNoColon(currencyId, "currencyId")}:${ensureNoColon(xpubOrAddress, "xpubOrAddress")}:${ensureNoColon(derivationMode, "derivationMode")}`;
|
|
18
36
|
}
|
|
19
37
|
exports.encodeAccountId = encodeAccountId;
|
|
20
38
|
function encodeTokenAccountId(accountId, token) {
|
|
21
|
-
return accountId + "+" +
|
|
39
|
+
return accountId + "+" + safeEncodeTokenId(token.id);
|
|
22
40
|
}
|
|
23
41
|
exports.encodeTokenAccountId = encodeTokenAccountId;
|
|
24
42
|
function decodeTokenAccountId(id) {
|
|
25
43
|
const [accountId, tokenId] = id.split("+");
|
|
26
|
-
const decodedTokenId =
|
|
44
|
+
const decodedTokenId = safeDecodeTokenId(tokenId);
|
|
27
45
|
let token = (0, currencies_1.findTokenById)(decodedTokenId);
|
|
28
46
|
if (!token) {
|
|
29
47
|
const { currencyId } = decodeAccountId(accountId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountId.js","sourceRoot":"","sources":["../../src/account/accountId.ts"],"names":[],"mappings":";;;;;;AAAA,6DAAqC;AACrC,0DAAkC;AAClC,8CAAiD;AACjD,8CAAqE;AACrE,yDAAsE;AAItE,SAAS,aAAa,CAAC,KAAa,EAAE,GAAW;IAC/C,IAAA,mBAAS,EAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,6CAA6C,EAAE,GAAG,CAAC,CAAC;IACpF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,UAAU,EACV,aAAa,EACb,cAAc,GACE;IAChB,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,aAAa,CACzF,UAAU,EACV,YAAY,CACb,IAAI,aAAa,CAAC,aAAa,EAAE,eAAe,CAAC,IAAI,aAAa,CACjE,cAAc,EACd,gBAAgB,CACjB,EAAE,CAAC;AACN,CAAC;AAdD,0CAcC;AACD,SAAgB,oBAAoB,CAAC,SAAiB,EAAE,KAAoB;IAC1E,OAAO,SAAS,GAAG,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"accountId.js","sourceRoot":"","sources":["../../src/account/accountId.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountId.unit.test.d.ts","sourceRoot":"","sources":["../../src/account/accountId.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const accountId_1 = require("./accountId");
|
|
4
|
+
const currencies_1 = require("../currencies");
|
|
5
|
+
describe("coin-framework", () => {
|
|
6
|
+
describe("accountId", () => {
|
|
7
|
+
describe("safeEncodeTokenId", () => {
|
|
8
|
+
it("shouldn't throw with falsy tokenId", () => {
|
|
9
|
+
expect((0, accountId_1.safeEncodeTokenId)(null)).toBe("");
|
|
10
|
+
expect((0, accountId_1.safeEncodeTokenId)(undefined)).toBe("");
|
|
11
|
+
expect((0, accountId_1.safeEncodeTokenId)("")).toBe("");
|
|
12
|
+
});
|
|
13
|
+
it("should encode a token id by making it URI encoded and remove characters used for accountId splitting", () => {
|
|
14
|
+
const tokenId = "foo/bar-baz_qux+fred thud0123°?=/&$";
|
|
15
|
+
expect((0, accountId_1.safeEncodeTokenId)(tokenId)).not.toMatch(
|
|
16
|
+
// should match with any character exect those
|
|
17
|
+
new RegExp("[^a-z0-9.!~*'()%]", "gi"));
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe("safeDecodeTokenId", () => {
|
|
21
|
+
it("shouldn't throw with falsy encodedTokenId", () => {
|
|
22
|
+
expect((0, accountId_1.safeDecodeTokenId)(null)).toBe("");
|
|
23
|
+
expect((0, accountId_1.safeDecodeTokenId)(undefined)).toBe("");
|
|
24
|
+
expect((0, accountId_1.safeDecodeTokenId)("")).toBe("");
|
|
25
|
+
});
|
|
26
|
+
it("should decode a token id and remove all obfuscation", () => {
|
|
27
|
+
const encodedTokenId = "foo%2Fbar~!dash!~baz~!underscore!~qux%2Bfred%20thud0123456789%C2%B0";
|
|
28
|
+
expect((0, accountId_1.safeDecodeTokenId)(encodedTokenId)).toBe("foo/bar-baz_qux+fred thud0123456789°");
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
describe("encodeTokenAccountId", () => {
|
|
32
|
+
it("should return an URI and splitting safe tokenAccountId (no + - _ % \\ /)", () => {
|
|
33
|
+
const accountId = "js:2:0xkvn:";
|
|
34
|
+
const token = (0, currencies_1.getTokenById)("bsc/bep20/binance-peg_dai_token");
|
|
35
|
+
const tokenAccountId = (0, accountId_1.encodeTokenAccountId)(accountId, token);
|
|
36
|
+
expect(tokenAccountId).toBe("js:2:0xkvn:+bsc%2Fbep20%2Fbinance~!dash!~peg~!underscore!~dai~!underscore!~token");
|
|
37
|
+
expect(tokenAccountId).not.toMatch(
|
|
38
|
+
// should match with any character exect those
|
|
39
|
+
new RegExp("[^a-z0-9.!~*'()%:+]", "gi"));
|
|
40
|
+
// Should only contain 1 + character
|
|
41
|
+
expect(tokenAccountId.split("+").length).toBe(2);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe("decodeTokenAccountId", () => {
|
|
45
|
+
it("should return an accountId and a token", () => {
|
|
46
|
+
expect((0, accountId_1.decodeTokenAccountId)("js:2:0xkvn:+bsc%2Fbep20%2Fbinance~!dash!~peg~!underscore!~dai~!underscore!~token")).toEqual({
|
|
47
|
+
accountId: "js:2:0xkvn:",
|
|
48
|
+
token: (0, currencies_1.getTokenById)("bsc/bep20/binance-peg_dai_token"),
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=accountId.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountId.unit.test.js","sourceRoot":"","sources":["../../src/account/accountId.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AccountIdParams, DerivationMode } from "@ledgerhq/types-live";
|
|
2
2
|
import type { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
3
|
+
export declare function safeEncodeTokenId(tokenId: string): string;
|
|
4
|
+
export declare function safeDecodeTokenId(encodedTokenId: string): string;
|
|
3
5
|
export declare function encodeAccountId({ type, version, currencyId, xpubOrAddress, derivationMode, }: AccountIdParams): string;
|
|
4
6
|
export declare function encodeTokenAccountId(accountId: string, token: TokenCurrency): string;
|
|
5
7
|
export declare function decodeTokenAccountId(id: string): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountId.d.ts","sourceRoot":"","sources":["../../src/account/accountId.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAOlF,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,UAAU,EACV,aAAa,EACb,cAAc,GACf,EAAE,eAAe,GAAG,MAAM,CAQ1B;AACD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAEpF;AACD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CACzC,CAYA;AACD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAYlE;AAGD,wBAAgB,aAAa,CAAC,EAC5B,cAAc,EACd,cAAc,EACd,QAAQ,GACT,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,cAAc,CAAC;CAC1B,GAAG,MAAM,CAET;AACD,eAAO,MAAM,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAS7E,CAAC"}
|
|
1
|
+
{"version":3,"file":"accountId.d.ts","sourceRoot":"","sources":["../../src/account/accountId.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAOlF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAShE;AAED,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,UAAU,EACV,aAAa,EACb,cAAc,GACf,EAAE,eAAe,GAAG,MAAM,CAQ1B;AACD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAEpF;AACD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CACzC,CAYA;AACD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAYlE;AAGD,wBAAgB,aAAa,CAAC,EAC5B,cAAc,EACd,cAAc,EACd,QAAQ,GACT,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,cAAc,CAAC;CAC1B,GAAG,MAAM,CAET;AACD,eAAO,MAAM,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAS7E,CAAC"}
|
|
@@ -7,15 +7,31 @@ function ensureNoColon(value, ctx) {
|
|
|
7
7
|
invariant(!value.includes(":"), "AccountId '%s' component must not use colon", ctx);
|
|
8
8
|
return value;
|
|
9
9
|
}
|
|
10
|
+
export function safeEncodeTokenId(tokenId) {
|
|
11
|
+
if (!tokenId)
|
|
12
|
+
return "";
|
|
13
|
+
const URIEncoded = encodeURIComponent(tokenId);
|
|
14
|
+
const dashUnderscoreSafe = URIEncoded.replace(/-/g, "~!dash!~").replace(/_/g, "~!underscore!~");
|
|
15
|
+
return dashUnderscoreSafe;
|
|
16
|
+
}
|
|
17
|
+
export function safeDecodeTokenId(encodedTokenId) {
|
|
18
|
+
if (!encodedTokenId)
|
|
19
|
+
return "";
|
|
20
|
+
const dashUnderscoreUnsafe = encodedTokenId
|
|
21
|
+
.replace(/~!dash!~/g, "-")
|
|
22
|
+
.replace(/~!underscore!~/g, "_");
|
|
23
|
+
const decodedURIComponent = decodeURIComponent(dashUnderscoreUnsafe);
|
|
24
|
+
return decodedURIComponent;
|
|
25
|
+
}
|
|
10
26
|
export function encodeAccountId({ type, version, currencyId, xpubOrAddress, derivationMode, }) {
|
|
11
27
|
return `${ensureNoColon(type, "type")}:${ensureNoColon(version, "version")}:${ensureNoColon(currencyId, "currencyId")}:${ensureNoColon(xpubOrAddress, "xpubOrAddress")}:${ensureNoColon(derivationMode, "derivationMode")}`;
|
|
12
28
|
}
|
|
13
29
|
export function encodeTokenAccountId(accountId, token) {
|
|
14
|
-
return accountId + "+" +
|
|
30
|
+
return accountId + "+" + safeEncodeTokenId(token.id);
|
|
15
31
|
}
|
|
16
32
|
export function decodeTokenAccountId(id) {
|
|
17
33
|
const [accountId, tokenId] = id.split("+");
|
|
18
|
-
const decodedTokenId =
|
|
34
|
+
const decodedTokenId = safeDecodeTokenId(tokenId);
|
|
19
35
|
let token = findTokenById(decodedTokenId);
|
|
20
36
|
if (!token) {
|
|
21
37
|
const { currencyId } = decodeAccountId(accountId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountId.js","sourceRoot":"","sources":["../../src/account/accountId.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,gBAAgB,CAAC;AACrC,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAItE,SAAS,aAAa,CAAC,KAAa,EAAE,GAAW;IAC/C,SAAS,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,6CAA6C,EAAE,GAAG,CAAC,CAAC;IACpF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,UAAU,EACV,aAAa,EACb,cAAc,GACE;IAChB,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,aAAa,CACzF,UAAU,EACV,YAAY,CACb,IAAI,aAAa,CAAC,aAAa,EAAE,eAAe,CAAC,IAAI,aAAa,CACjE,cAAc,EACd,gBAAgB,CACjB,EAAE,CAAC;AACN,CAAC;AACD,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,KAAoB;IAC1E,OAAO,SAAS,GAAG,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"accountId.js","sourceRoot":"","sources":["../../src/account/accountId.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountId.unit.test.d.ts","sourceRoot":"","sources":["../../src/account/accountId.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { decodeTokenAccountId, encodeTokenAccountId, safeDecodeTokenId, safeEncodeTokenId, } from "./accountId";
|
|
2
|
+
import { getTokenById } from "../currencies";
|
|
3
|
+
describe("coin-framework", () => {
|
|
4
|
+
describe("accountId", () => {
|
|
5
|
+
describe("safeEncodeTokenId", () => {
|
|
6
|
+
it("shouldn't throw with falsy tokenId", () => {
|
|
7
|
+
expect(safeEncodeTokenId(null)).toBe("");
|
|
8
|
+
expect(safeEncodeTokenId(undefined)).toBe("");
|
|
9
|
+
expect(safeEncodeTokenId("")).toBe("");
|
|
10
|
+
});
|
|
11
|
+
it("should encode a token id by making it URI encoded and remove characters used for accountId splitting", () => {
|
|
12
|
+
const tokenId = "foo/bar-baz_qux+fred thud0123°?=/&$";
|
|
13
|
+
expect(safeEncodeTokenId(tokenId)).not.toMatch(
|
|
14
|
+
// should match with any character exect those
|
|
15
|
+
new RegExp("[^a-z0-9.!~*'()%]", "gi"));
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe("safeDecodeTokenId", () => {
|
|
19
|
+
it("shouldn't throw with falsy encodedTokenId", () => {
|
|
20
|
+
expect(safeDecodeTokenId(null)).toBe("");
|
|
21
|
+
expect(safeDecodeTokenId(undefined)).toBe("");
|
|
22
|
+
expect(safeDecodeTokenId("")).toBe("");
|
|
23
|
+
});
|
|
24
|
+
it("should decode a token id and remove all obfuscation", () => {
|
|
25
|
+
const encodedTokenId = "foo%2Fbar~!dash!~baz~!underscore!~qux%2Bfred%20thud0123456789%C2%B0";
|
|
26
|
+
expect(safeDecodeTokenId(encodedTokenId)).toBe("foo/bar-baz_qux+fred thud0123456789°");
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe("encodeTokenAccountId", () => {
|
|
30
|
+
it("should return an URI and splitting safe tokenAccountId (no + - _ % \\ /)", () => {
|
|
31
|
+
const accountId = "js:2:0xkvn:";
|
|
32
|
+
const token = getTokenById("bsc/bep20/binance-peg_dai_token");
|
|
33
|
+
const tokenAccountId = encodeTokenAccountId(accountId, token);
|
|
34
|
+
expect(tokenAccountId).toBe("js:2:0xkvn:+bsc%2Fbep20%2Fbinance~!dash!~peg~!underscore!~dai~!underscore!~token");
|
|
35
|
+
expect(tokenAccountId).not.toMatch(
|
|
36
|
+
// should match with any character exect those
|
|
37
|
+
new RegExp("[^a-z0-9.!~*'()%:+]", "gi"));
|
|
38
|
+
// Should only contain 1 + character
|
|
39
|
+
expect(tokenAccountId.split("+").length).toBe(2);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe("decodeTokenAccountId", () => {
|
|
43
|
+
it("should return an accountId and a token", () => {
|
|
44
|
+
expect(decodeTokenAccountId("js:2:0xkvn:+bsc%2Fbep20%2Fbinance~!dash!~peg~!underscore!~dai~!underscore!~token")).toEqual({
|
|
45
|
+
accountId: "js:2:0xkvn:",
|
|
46
|
+
token: getTokenById("bsc/bep20/binance-peg_dai_token"),
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=accountId.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountId.unit.test.js","sourceRoot":"","sources":["../../src/account/accountId.unit.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/account/accountId.ts
CHANGED
|
@@ -11,6 +11,26 @@ function ensureNoColon(value: string, ctx: string): string {
|
|
|
11
11
|
return value;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export function safeEncodeTokenId(tokenId: string): string {
|
|
15
|
+
if (!tokenId) return "";
|
|
16
|
+
|
|
17
|
+
const URIEncoded = encodeURIComponent(tokenId);
|
|
18
|
+
const dashUnderscoreSafe = URIEncoded.replace(/-/g, "~!dash!~").replace(/_/g, "~!underscore!~");
|
|
19
|
+
|
|
20
|
+
return dashUnderscoreSafe;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function safeDecodeTokenId(encodedTokenId: string): string {
|
|
24
|
+
if (!encodedTokenId) return "";
|
|
25
|
+
|
|
26
|
+
const dashUnderscoreUnsafe = encodedTokenId
|
|
27
|
+
.replace(/~!dash!~/g, "-")
|
|
28
|
+
.replace(/~!underscore!~/g, "_");
|
|
29
|
+
const decodedURIComponent = decodeURIComponent(dashUnderscoreUnsafe);
|
|
30
|
+
|
|
31
|
+
return decodedURIComponent;
|
|
32
|
+
}
|
|
33
|
+
|
|
14
34
|
export function encodeAccountId({
|
|
15
35
|
type,
|
|
16
36
|
version,
|
|
@@ -27,14 +47,14 @@ export function encodeAccountId({
|
|
|
27
47
|
)}`;
|
|
28
48
|
}
|
|
29
49
|
export function encodeTokenAccountId(accountId: string, token: TokenCurrency): string {
|
|
30
|
-
return accountId + "+" +
|
|
50
|
+
return accountId + "+" + safeEncodeTokenId(token.id);
|
|
31
51
|
}
|
|
32
52
|
export function decodeTokenAccountId(id: string): {
|
|
33
53
|
accountId: string;
|
|
34
54
|
token: TokenCurrency | null | undefined;
|
|
35
55
|
} {
|
|
36
56
|
const [accountId, tokenId] = id.split("+");
|
|
37
|
-
const decodedTokenId =
|
|
57
|
+
const decodedTokenId = safeDecodeTokenId(tokenId);
|
|
38
58
|
let token = findTokenById(decodedTokenId);
|
|
39
59
|
if (!token) {
|
|
40
60
|
const { currencyId } = decodeAccountId(accountId);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeTokenAccountId,
|
|
3
|
+
encodeTokenAccountId,
|
|
4
|
+
safeDecodeTokenId,
|
|
5
|
+
safeEncodeTokenId,
|
|
6
|
+
} from "./accountId";
|
|
7
|
+
import { getTokenById } from "../currencies";
|
|
8
|
+
|
|
9
|
+
describe("coin-framework", () => {
|
|
10
|
+
describe("accountId", () => {
|
|
11
|
+
describe("safeEncodeTokenId", () => {
|
|
12
|
+
it("shouldn't throw with falsy tokenId", () => {
|
|
13
|
+
expect(safeEncodeTokenId(null as any)).toBe("");
|
|
14
|
+
expect(safeEncodeTokenId(undefined as any)).toBe("");
|
|
15
|
+
expect(safeEncodeTokenId("")).toBe("");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should encode a token id by making it URI encoded and remove characters used for accountId splitting", () => {
|
|
19
|
+
const tokenId = "foo/bar-baz_qux+fred thud0123°?=/&$";
|
|
20
|
+
|
|
21
|
+
expect(safeEncodeTokenId(tokenId)).not.toMatch(
|
|
22
|
+
// should match with any character exect those
|
|
23
|
+
new RegExp("[^a-z0-9.!~*'()%]", "gi"),
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe("safeDecodeTokenId", () => {
|
|
28
|
+
it("shouldn't throw with falsy encodedTokenId", () => {
|
|
29
|
+
expect(safeDecodeTokenId(null as any)).toBe("");
|
|
30
|
+
expect(safeDecodeTokenId(undefined as any)).toBe("");
|
|
31
|
+
expect(safeDecodeTokenId("")).toBe("");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("should decode a token id and remove all obfuscation", () => {
|
|
35
|
+
const encodedTokenId =
|
|
36
|
+
"foo%2Fbar~!dash!~baz~!underscore!~qux%2Bfred%20thud0123456789%C2%B0";
|
|
37
|
+
|
|
38
|
+
expect(safeDecodeTokenId(encodedTokenId)).toBe("foo/bar-baz_qux+fred thud0123456789°");
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("encodeTokenAccountId", () => {
|
|
43
|
+
it("should return an URI and splitting safe tokenAccountId (no + - _ % \\ /)", () => {
|
|
44
|
+
const accountId = "js:2:0xkvn:";
|
|
45
|
+
const token = getTokenById("bsc/bep20/binance-peg_dai_token");
|
|
46
|
+
|
|
47
|
+
const tokenAccountId = encodeTokenAccountId(accountId, token);
|
|
48
|
+
expect(tokenAccountId).toBe(
|
|
49
|
+
"js:2:0xkvn:+bsc%2Fbep20%2Fbinance~!dash!~peg~!underscore!~dai~!underscore!~token",
|
|
50
|
+
);
|
|
51
|
+
expect(tokenAccountId).not.toMatch(
|
|
52
|
+
// should match with any character exect those
|
|
53
|
+
new RegExp("[^a-z0-9.!~*'()%:+]", "gi"),
|
|
54
|
+
);
|
|
55
|
+
// Should only contain 1 + character
|
|
56
|
+
expect(tokenAccountId.split("+").length).toBe(2);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe("decodeTokenAccountId", () => {
|
|
61
|
+
it("should return an accountId and a token", () => {
|
|
62
|
+
expect(
|
|
63
|
+
decodeTokenAccountId(
|
|
64
|
+
"js:2:0xkvn:+bsc%2Fbep20%2Fbinance~!dash!~peg~!underscore!~dai~!underscore!~token",
|
|
65
|
+
),
|
|
66
|
+
).toEqual({
|
|
67
|
+
accountId: "js:2:0xkvn:",
|
|
68
|
+
token: getTokenById("bsc/bep20/binance-peg_dai_token"),
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|