Skip to content

Commit 0c9d676

Browse files
authored
Merge pull request #793 from symbol/dev
Dev -> Main
2 parents a49d14b + 322dc72 commit 0c9d676

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+11377
-198
lines changed

.DS_Store

6 KB
Binary file not shown.

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ ts-docs/
1515
.travis
1616
*.iml
1717
*.log
18+
.npm-pack-all-tmp

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
44

55
The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

7+
## [1.0.2] - 19-Oct-2021
8+
9+
**Milestone**: Symbol Mainnet
10+
Package | Version | Link
11+
---|---|---
12+
SDK Core| v1.0.2 | [symbol-sdk](https://www.npmjs.com/package/symbol-sdk)
13+
Catbuffer | v1.0.1 | [catbuffer-typescript](https://www.npmjs.com/package/catbuffer-typescript)
14+
Client Library | v1.0.1 | [symbol-openapi-typescript-fetch-client](https://www.npmjs.com/package/symbol-openapi-typescript-fetch-client)
15+
16+
- feat: Multisig multilevel subscription in web listener.
17+
- feat: Added Deployment data to `ServerInfo`.
18+
- fix: Announce method missing observable map.
19+
- fix: Allowing plain base32 addresses in rest payloads. Both address formats are supported.
20+
- fix: Cosigning from transaction hash only.
21+
- fix: Transaction signWith method broken into smaller methods.
22+
723
## [1.0.1] - 24-May-2021
824

925
**Milestone**: Symbol Mainnet

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The Symbol SDK for TypeScript / JavaScript allows you to develop web, mobile, an
1111

1212
### _Catapult-Server_ Network Compatibility ([email protected])
1313

14-
Symbol network launched [catapult-server](https://github.com/nemtech/catapult-server/releases/tag/v1.0.0.0), **it is recommended to use this package's 1.0.0 version and upwards for the Symbol public network**.
14+
Symbol network launched [catapult-client](https://github.com/symbol/catapult-client/releases/tag/v1.0.0.0), **it is recommended to use this package's 1.0.0 version and upwards for the Symbol public network**.
1515

1616
Find the complete release notes [here](CHANGELOG.md).
1717

@@ -40,7 +40,7 @@ Use the following available resources to get help:
4040

4141
- [Symbol Documentation][docs]
4242
- [Symbol SDK Typescript/Javascript Reference][sdk-ref]
43-
- Join the community [slack group (#sig-api)][slack]
43+
- Join the community [Discord server][discord]
4444
- If you found a bug, [open a new issue][issues]
4545

4646
## Contributing
@@ -55,9 +55,9 @@ You can also find useful notes for developers under our documentation [guideline
5555
Copyright (c) 2018-present NEM
5656
Licensed under the [Apache License 2.0](LICENSE)
5757

58-
[self]: https://github.com/nemtech/symbol-sdk-typescript-javascript
59-
[docs]: http://nemtech.github.io/getting-started/setup-workstation.html
60-
[issues]: https://github.com/nemtech/symbol-sdk-typescript-javascript/issues
61-
[sdk-ref]: https://nemtech.github.io/references/typescript-sdk.html
62-
[guidelines]: https://nemtech.github.io/contribute/contributing.html#sdk
63-
[slack]: https://join.slack.com/t/nem2/shared_invite/enQtMzY4MDc2NTg0ODgyLWZmZWRiMjViYTVhZjEzOTA0MzUyMTA1NTA5OWQ0MWUzNTA4NjM5OTJhOGViOTBhNjkxYWVhMWRiZDRkOTE0YmU
58+
[self]: https://github.com/symbol/symbol-sdk-typescript-javascript
59+
[docs]: http://docs.symbolplatform.com/getting-started/setup-workstation.html
60+
[issues]: https://github.com/symbol/symbol-sdk-typescript-javascript/issues
61+
[sdk-ref]: https://docs.symbolplatform.com/references/typescript-sdk.html
62+
[guidelines]: https://docs.symbolplatform.com/contribute/contributing.html#sdk
63+
[discord]: https://discord.com/invite/xymcity

package-lock.json

Lines changed: 10787 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
"dependencies": {
9999
"@js-joda/core": "^3.2.0",
100100
"bluebird": "^3.7.2",
101-
"catbuffer-typescript": "0.1.1",
101+
"catbuffer-typescript": "1.0.0",
102102
"crypto-js": "^4.0.0",
103103
"diff": "^4.0.2",
104104
"futoin-hkdf": "^1.3.2",
@@ -110,9 +110,9 @@
110110
"minimist": "^1.2.5",
111111
"node-fetch": "^2.6.0",
112112
"ripemd160": "^2.0.2",
113-
"rxjs": "^6.6.3",
113+
"rxjs": "^6.6.7",
114114
"rxjs-compat": "^6.6.3",
115-
"symbol-openapi-typescript-fetch-client": "0.11.2",
115+
"symbol-openapi-typescript-fetch-client": "^1.0.2",
116116
"tweetnacl": "^1.0.3",
117117
"utf8": "^2.1.2",
118118
"ws": "^7.3.1"

src/core/format/Utilities.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,18 @@ export const decodeBlock = (input: any, inputOffset: number, output: any, output
173173
output[outputOffset + 3] = ((bytes[4] & 0x01) << 7) | (bytes[5] << 2) | (bytes[6] >> 3);
174174
output[outputOffset + 4] = ((bytes[6] & 0x07) << 5) | bytes[7];
175175
};
176+
177+
/**
178+
* Traverses the tree object to pick addresses strings.
179+
* @param {array} array of multisig children
180+
* @param {parse} function to parse tree and pick children addresses
181+
*/
182+
export const parseObjectProperties = (obj: [], parse): any => {
183+
for (const k in obj) {
184+
if (typeof obj[k] === 'object' && obj[k] !== null) {
185+
parseObjectProperties(obj[k], parse);
186+
} else if (Object.prototype.hasOwnProperty.call(obj, k)) {
187+
parse(k, obj[k]);
188+
}
189+
}
190+
};

src/core/utils/DtoMapping.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { MerkleTreeBranch } from '../../model/state/MerkleTreeBranch';
3434
import { MerkleTreeBranchLink } from '../../model/state/MerkleTreeBranchLink';
3535
import { MerkleTreeLeaf } from '../../model/state/MerkleTreeLeaf';
3636
import { MerkleTreeNodeType } from '../../model/state/MerkleTreeNodeType';
37+
import { Convert } from '../format';
3738

3839
export class DtoMapping {
3940
/**
@@ -45,7 +46,7 @@ export class DtoMapping {
4546
return new AccountRestrictions(
4647
accountRestrictions.accountRestrictions.version || 1,
4748
accountRestrictions['id'],
48-
Address.createFromEncoded(accountRestrictions.accountRestrictions.address),
49+
DtoMapping.toAddress(accountRestrictions.accountRestrictions.address),
4950
accountRestrictions.accountRestrictions.restrictions.map((prop) => {
5051
const restrictionFlags = prop.restrictionFlags as number;
5152
switch (restrictionFlags) {
@@ -55,7 +56,7 @@ export class DtoMapping {
5556
case AddressRestrictionFlag.BlockOutgoingAddress:
5657
return new AccountRestriction(
5758
restrictionFlags,
58-
prop.values.map((value) => Address.createFromEncoded(value as string)),
59+
prop.values.map((value) => DtoMapping.toAddress(value as string)),
5960
);
6061
case MosaicRestrictionFlag.AllowMosaic:
6162
case MosaicRestrictionFlag.BlockMosaic:
@@ -76,6 +77,22 @@ export class DtoMapping {
7677
);
7778
}
7879

80+
/**
81+
* This method knows how to convert an address payload sent by Rest to Address.
82+
*
83+
* Currently rest sends hex encoded addresses, it is desired to use base32 encoded addresses.
84+
*
85+
* This method handles both format, encoded (deprecated) and base32 encoded addresses.
86+
*
87+
* Clients using this SDK will be able to process both payloads.
88+
*
89+
* @param value the address in encoded (6823BB7C3C089D996585466380EDBDC19D4959184893E38C) format or decoded/plain format (SB3KUBHATFCPV7UZQLWAQ2EUR6SIHBSBEOEDDDF3)
90+
* @return the Address object.
91+
*/
92+
public static toAddress(value: string): Address {
93+
return Convert.isHexString(value, 48) ? Address.createFromEncoded(value) : Address.createFromRawAddress(value);
94+
}
95+
7996
/**
8097
* Creates a copy of the first object adding the attributes of the second object.
8198
* @param object the object to be cloned

src/core/utils/MultisigGraphUtils.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2020 NEM
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { MultisigAccountGraphInfo } from '../../model/account/MultisigAccountGraphInfo';
18+
import { MultisigAccountInfo } from '../../model/account/MultisigAccountInfo';
19+
20+
/**
21+
* MultisigGraph utilities
22+
*/
23+
24+
// Type for Multisig Tree children Object
25+
export type MultisigChildrenTreeObject = {
26+
address: string;
27+
children: []; // children array.
28+
};
29+
30+
export class MultisigGraphUtils {
31+
/**
32+
* creates a structred Tree object containing Current multisig account with children
33+
* @param {MultisigAccountInfo[][]} multisigEnteries
34+
* @returns {MultisigChildrenTreeObject[]} Array of multisigChildrentTree objects
35+
*/
36+
public static getMultisigChildren(multisigAccountGraphInfoMapped: MultisigAccountInfo[][]): MultisigChildrenTreeObject[] {
37+
if (multisigAccountGraphInfoMapped) {
38+
const mappedTree: MultisigChildrenTreeObject[] = [];
39+
multisigAccountGraphInfoMapped.forEach((level: MultisigAccountInfo[]) => {
40+
level.forEach((entry: MultisigAccountInfo) => {
41+
mappedTree.push({
42+
address: entry.accountAddress.plain(),
43+
children: [],
44+
});
45+
// find the entry matching with address matching cosignatory address and update his children
46+
const updateRecursively = (address: string, object: MultisigChildrenTreeObject) => (obj): any => {
47+
if (obj.address === address) {
48+
obj.children.push(object);
49+
} else if (obj.children) {
50+
obj.children.forEach(updateRecursively(address, object));
51+
}
52+
};
53+
entry.cosignatoryAddresses.forEach((addressVal) => {
54+
mappedTree.forEach(
55+
updateRecursively(addressVal['address'], {
56+
address: entry.accountAddress.plain(),
57+
children: [],
58+
}),
59+
);
60+
});
61+
});
62+
});
63+
return mappedTree;
64+
}
65+
return [];
66+
}
67+
/**
68+
* sort entries based on tree hierarchy from top to bottom
69+
* @param {Map<number, MultisigAccountInfo[]>} multisigEnteries
70+
* @returns {MultisigAccountInfo[]} sorted multisig graph
71+
*/
72+
private static getMultisigGraphArraySorted(multisigEntries: Map<number, MultisigAccountInfo[]>): MultisigAccountInfo[][] {
73+
return [...multisigEntries.keys()]
74+
.sort((a, b) => b - a) // Get addresses from top to bottom
75+
.map((key) => multisigEntries.get(key) || [])
76+
.filter((x) => x.length > 0);
77+
}
78+
/**
79+
* returns sorted tree entries
80+
* @param {MultisigAccountGraphInfo} graphInfo
81+
* @returns {MultisigAccountInfo[][]} array of sorted multisigInfo
82+
*/
83+
public static getMultisigInfoFromMultisigGraphInfo(graphInfo: MultisigAccountGraphInfo): MultisigAccountInfo[][] {
84+
const { multisigEntries } = graphInfo;
85+
return [...this.getMultisigGraphArraySorted(multisigEntries)].map((item) => item);
86+
}
87+
}

src/core/utils/UnresolvedMapping.ts

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { NamespaceId } from '../../model/namespace/NamespaceId';
2121
import { NetworkType } from '../../model/network/NetworkType';
2222
import { Convert } from '../format/Convert';
2323
import { RawAddress } from '../format/RawAddress';
24+
import { DtoMapping } from './DtoMapping';
2425

2526
/**
2627
* @internal
@@ -48,26 +49,40 @@ export class UnresolvedMapping {
4849
}
4950

5051
/**
51-
* Map unresolved address string to Address or NamespaceId
52-
* @param {string} address The unresolved address in hex
52+
* Map unresolved address string to Address or NamespaceId.
53+
*
54+
* Input examples:
55+
* - 6826D27E1D0A26CA4E316F901E23E55C8711DB20DF45C536 Hex address (old rest)
56+
* - NATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA35C4KNQ Base32 address (new reset)
57+
* - 99C2860B73398FD8D3000000000000000000000000000000 Hex namespace id (old rest)
58+
* - THBIMC3THGH5RUYAAAAAAAAAAAAAAAAAAAAAAAA Base32 namespace id (new rest)
59+
*
60+
* @param {string} unresolvedAddressString The unresolved address in hex (old rest) or base32 address (new rest)
5361
* @returns {UnresolvedAddress}
5462
*/
55-
public static toUnresolvedAddress(address: string): UnresolvedAddress {
56-
if (!Convert.isHexString(address)) {
57-
throw new Error('Input string is not in valid hexadecimal notation.');
58-
}
59-
// If bit 0 of byte 0 is not set (like in 0x90), then it is a regular address.
60-
// Else (e.g. 0x91) it represents a namespace id which starts at byte 1.
61-
const bit0 = Convert.hexToUint8(address.substr(1, 2))[0];
62-
if ((bit0 & 16) === 16) {
63-
// namespaceId encoded hexadecimal notation provided
64-
// only 8 bytes are relevant to resolve the NamespaceId
65-
const relevantPart = address.substr(2, 16);
66-
return NamespaceId.createFromEncoded(Convert.uint8ToHex(Convert.hexToUint8Reverse(relevantPart)));
67-
}
63+
public static toUnresolvedAddress(unresolvedAddressString: string): UnresolvedAddress {
64+
const fromHexToUnresolvedAddress = (unresolvedAddressStringHex: string) => {
65+
// If bit 0 of byte 0 is not set (like in 0x90), then it is a regular address.
66+
// Else (e.g. 0x91) it represents a namespace id which starts at byte 1.
67+
const bit0 = Convert.hexToUint8(unresolvedAddressStringHex.substr(1, 2))[0];
68+
if ((bit0 & 16) === 16) {
69+
// namespaceId encoded hexadecimal notation provided
70+
// only 8 bytes are relevant to resolve the NamespaceId
71+
const relevantPart = unresolvedAddressStringHex.substr(2, 16);
72+
return NamespaceId.createFromEncoded(Convert.uint8ToHex(Convert.hexToUint8Reverse(relevantPart)));
73+
}
6874

69-
// read address from encoded hexadecimal notation
70-
return Address.createFromEncoded(address);
75+
// read address from encoded hexadecimal notation
76+
return Address.createFromEncoded(unresolvedAddressStringHex);
77+
};
78+
79+
if (Convert.isHexString(unresolvedAddressString, 48)) {
80+
// Old Rest
81+
return fromHexToUnresolvedAddress(unresolvedAddressString);
82+
} else {
83+
// New rest
84+
return fromHexToUnresolvedAddress(DtoMapping.toAddress(unresolvedAddressString).encoded());
85+
}
7186
}
7287

7388
/**

0 commit comments

Comments
 (0)