diff --git a/CHANGELOG.md b/CHANGELOG.md index c5eabbef..907337fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## master + +Changes: + +- Cater for Ethereum-compatible multisig addresses + + ## 3.1.1 Mar 19, 2023 Changes: diff --git a/packages/ui-keyring/src/Base.ts b/packages/ui-keyring/src/Base.ts index fb6611ff..44348371 100644 --- a/packages/ui-keyring/src/Base.ts +++ b/packages/ui-keyring/src/Base.ts @@ -22,6 +22,8 @@ export class Base { #contracts: AddressSubject; + #isEthereum: boolean; + #keyring?: KeyringInstance; protected _store: KeyringStore; @@ -34,6 +36,7 @@ export class Base { this.#accounts = accounts; this.#addresses = addresses; this.#contracts = contracts; + this.#isEthereum = false; this._store = new BrowserStore(); } @@ -49,6 +52,10 @@ export class Base { return this.#contracts; } + public get isEthereum (): boolean { + return this.#isEthereum; + } + public get keyring (): KeyringInstance { if (this.#keyring) { return this.#keyring; @@ -117,6 +124,9 @@ export class Base { this.setDevMode(options.isDevelopment); } + // set Ethereum state + this.#isEthereum = keyring.type === 'ethereum'; + this.#keyring = keyring; this._genesisHash = options.genesisHash && ( isString(options.genesisHash) diff --git a/packages/ui-keyring/src/Keyring.ts b/packages/ui-keyring/src/Keyring.ts index aa137338..ad934136 100644 --- a/packages/ui-keyring/src/Keyring.ts +++ b/packages/ui-keyring/src/Keyring.ts @@ -46,10 +46,20 @@ export class Keyring extends Base implements KeyringStruct { } public addMultisig (addresses: (string | Uint8Array)[], threshold: bigint | BN | number, meta: KeyringPair$Meta = {}): CreateResult { - const address = createKeyMulti(addresses, threshold); + let address = createKeyMulti(addresses, threshold); + + // For Ethereum chains, the first 20 bytes of the hash indicates the actual address + // Testcases via creation and on-chain events: + // - input: 0x7a1671a0224c8927b08f978027d586ab6868de0d31bb5bc956b625ced2ab18c4 + // - output: 0x7a1671a0224c8927b08f978027d586ab6868de0d + if (this.isEthereum) { + address = address.slice(0, 20); + } // we could use `sortAddresses`, but rather use internal encode/decode so we are 100% - const who = u8aSorted(addresses.map((who) => this.decodeAddress(who))).map((who) => this.encodeAddress(who)); + const who = u8aSorted( + addresses.map((who) => this.decodeAddress(who)) + ).map((who) => this.encodeAddress(who)); return this.addExternal(address, objectSpread({}, meta, { isMultisig: true, threshold: bnToBn(threshold).toNumber(), who })); }