diff --git a/package-lock.json b/package-lock.json index 573b96ea..e4fa6421 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.12", + "version": "2.0.0-beta.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.11", + "version": "2.0.0-beta.13", "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.7.0", diff --git a/package.json b/package.json index d7649a65..18d05682 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@terra-money/feather.js", - "version": "2.0.0-beta.12", + "version": "2.0.0-beta.13", "description": "The JavaScript SDK for Terra and Feather chains", "license": "MIT", "author": "Terraform Labs, PTE.", diff --git a/src/core/ibc-hooks/helpers/derive-sender.spec.ts b/src/core/ibc-hooks/helpers/derive-sender.spec.ts new file mode 100644 index 00000000..3217630a --- /dev/null +++ b/src/core/ibc-hooks/helpers/derive-sender.spec.ts @@ -0,0 +1,51 @@ +import { deriveIbcHooksSender } from './derive-sender'; + +describe('Must use DeriveIbcHooksSender to derive', () => { + it('a terra address successfully for channel-0 and prefix terra', () => { + const derived = deriveIbcHooksSender( + 'channel-0', + 'terra18qq9svm5tjywcysd549tzkk3ax04f43zml9xay', + 'terra' + ); + + expect(derived).toStrictEqual( + 'terra1qxyr66gyd6fjlr0826cce8fj4jg96hd5jdkg4e3e2hc3gl0r9zps9sc93t' + ); + }); + + it('a terra address successfully for channel-1 and prefix terra', () => { + const derived = deriveIbcHooksSender( + 'channel-1', + 'terra18qq9svm5tjywcysd549tzkk3ax04f43zml9xay', + 'terra' + ); + + expect(derived).toStrictEqual( + 'terra1tdx2llx7dxp245p32rl5xf85qtfhnsn477fs6man34lthdcmr6wsxntykd' + ); + }); + + it('a terra address successfully for channel-1 and prefix juno', () => { + const derived = deriveIbcHooksSender( + 'channel-0', + 'terra18qq9svm5tjywcysd549tzkk3ax04f43zml9xay', + 'juno' + ); + + expect(derived).toStrictEqual( + 'juno1qxyr66gyd6fjlr0826cce8fj4jg96hd5jdkg4e3e2hc3gl0r9zpsrpuvys' + ); + }); + + it('a juno address successfully for channel-0 and prefix terra', () => { + const derived = deriveIbcHooksSender( + 'channel-0', + 'juno1yd8m9u8gexcjectscrduxmtw60psndqhcd87jt', + 'terra' + ); + + expect(derived).toStrictEqual( + 'terra1njxpjzu233h4ctlsyvqq4nuxl5y5cu9lxuprnqmv574ddqkqu7zqxg6u3k' + ); + }); +}); diff --git a/src/core/ibc-hooks/helpers/derive-sender.ts b/src/core/ibc-hooks/helpers/derive-sender.ts new file mode 100644 index 00000000..aec14ba3 --- /dev/null +++ b/src/core/ibc-hooks/helpers/derive-sender.ts @@ -0,0 +1,43 @@ +import { AccAddress } from '../../../core/bech32'; +import { bech32 } from 'bech32'; +import { createHash } from 'crypto'; + +const senderPrefix = 'ibc-wasm-hook-intermediary'; + +// Function used to derive the counterparty chain address from the +// ibc channel, originSender and bech32prefix, for ibc-hooks. +// +// This function is ported to JS from the following Go code: +// https://github.com/cosmos/ibc-apps/blob/main/modules/ibc-hooks/keeper/keeper.go#L57-L62 +export const deriveIbcHooksSender = ( + channel: string, + originSender: AccAddress, + bech32Prefix: string +): AccAddress => { + const concatedAddress = `${channel}/${originSender}`; + const senderSHA256 = hash(senderPrefix, Buffer.from(concatedAddress)); + const words = bech32.toWords(senderSHA256); + + return bech32.encode(bech32Prefix, words).toString(); +}; + +// private function to derive the string hash, +// bassed on the following Go code: +// https://github.com/cosmos/cosmos-sdk/blob/release/v0.47.x/types/address/hash.go#L26-L39 +const hash = (typ: string, key: Buffer): Buffer => { + let hasher = createHash('sha256'); + + // Convert the string to a Buffer + const typeBuffer = Buffer.from(typ, 'utf-8'); + + // First hash + hasher.update(typeBuffer); + const th = hasher.digest(); + hasher = createHash('sha256'); + + // Reset the hasher and do the second hash + hasher.update(th); + hasher.update(key); + + return hasher.digest(); +}; diff --git a/src/core/ibc-hooks/index.ts b/src/core/ibc-hooks/index.ts new file mode 100644 index 00000000..8a929e26 --- /dev/null +++ b/src/core/ibc-hooks/index.ts @@ -0,0 +1 @@ +export * from './helpers/derive-sender';