UNPKG

@wormhole-foundation/sdk-cosmwasm

Version:

SDK for EVM chains, used in conjunction with @wormhole-foundation/sdk

212 lines (200 loc) 7.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CosmwasmAddress = void 0; const sdk_connect_1 = require("@wormhole-foundation/sdk-connect"); const constants_js_1 = require("./constants.js"); const types_js_1 = require("./types.js"); /* Cosmos Addresses ----- There are at least 5 types of addresses in Cosmos: Native Denom ex: "uatom" address = [] // 0 bytes domain = undefined denom = "uatom" denomType = "native" Contract Address ex: "wormhole1ctnjk7an90lz5wjfvr3cf6x984a8cjnv8dpmztmlpcq4xteaa2xs9pwmzk" address = [0x...] // 32 bytes domain = "wormhole" denom = undefined denomType = undefined Account Address ex: "cosmos1hsk6jryyqjfhp5dhc55tc9jtckygx0eph6dd02" address = [0x...] // 20 bytes domain = "cosmos" denom = undefined denomType = undefined IBC Denom ex: IBC/BAEAC83736444C09656FBE666FB625974FCCDEE566EB700EBFD2642C5F6CF13A address = [0x...] // 32 bytes domain = undefined denom = undefined denomType = "IBC" Factory Address ex: "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/avax" address = [0x...] 20 bytes domain = "inj" denom = "avax" denomType = "factory" Transfer Denom ex: transfer/channel-486/factory/wormhole1ctnjk7an90lz5wjfvr3cf6x984a8cjnv8dpmztmlpcq4xteaa2xs9pwmzk/6vxRV62YN1CTZeQM5ZfvCZDCVA4nLhtZcLxziYa7xYqb address = [0x...] 32 bytes domain = "wormhole" denom = "6vxRV62YN1CTZeQM5ZfvCZDCVA4nLhtZcLxziYa7xYqb" denomType = "transfer/channel-486/factory" */ // Factory type addresses may have hex or b64 or bech32 encoded addresses function tryDecode(data) { try { const decoded = sdk_connect_1.encoding.bech32.decodeToBytes(data); return { data: decoded.bytes, prefix: decoded.prefix }; } catch { } try { return { data: sdk_connect_1.encoding.hex.decode(data) }; } catch { } try { return { data: sdk_connect_1.encoding.b64.decode(data) }; } catch { } throw new Error(`Cannot decode: ${data}`); } class CosmwasmAddress { static contractAddressByteSize = 32; static accountAddressByteSize = 20; static platform = types_js_1._platform; // the actual bytes of the address address; // The domain is the prefix for the address, like "cosmos" or "ibc" domain; // The denom is the token name, like "uatom" or "usdc" denom; // The denomType is "native", "ibc", or "factory" denomType; constructor(address) { if (CosmwasmAddress.instanceof(address)) { const a = address; this.address = a.address; this.domain = a.domain; this.denom = a.denom; this.denomType = a.denomType; return; } if (typeof address === "string") { // A native denom like "uatom" if (address.length <= 8) { this.address = new Uint8Array(0); this.denom = address; this.denomType = "native"; return; } if (address.indexOf("/") !== -1) { // A denom address like "ibc/..." or "factory/..." or "transfer/channel-${id}/factory/..." const chunks = address.split("/"); // It's a `transfer/...` denom if (chunks.length >= 3) { // Address will be second from the last const { data, prefix } = tryDecode(chunks[chunks.length - 2]); this.address = data; this.domain = prefix; this.denom = chunks[chunks.length - 1]; this.denomType = chunks.slice(0, chunks.length - 2).join("/"); } else { const { data } = tryDecode(chunks[1]); this.address = data; this.denomType = chunks[0]; } } else { // should be a contract or account address by now if (!CosmwasmAddress.isValidAddress(address)) throw new Error(`Invalid Cosmwasm address: ${address}`); const { bytes: data, prefix } = sdk_connect_1.encoding.bech32.decodeToBytes(address); this.address = data; this.domain = prefix; } } else if (address instanceof Uint8Array) { this.address = address; } else if (sdk_connect_1.UniversalAddress.instanceof(address)) { this.address = address.toUint8Array(); } else throw new Error(`Invalid Cosmwasm address ${address}`); if (!CosmwasmAddress.validAddressLength(this.address)) { throw new Error("Expected 20 or 32 bytes address"); } } unwrap() { return this.toString(); } toString() { // Coin address if (this.denomType !== undefined) { // native asset denom if (this.denomType === "native") return this.denom; // ibc/hex if (this.denomType === "ibc") { // NOTE: this is case sensitive, should be `ibc` not `IBC` return `${this.denomType.toLowerCase()}/${sdk_connect_1.encoding.hex.encode(this.address).toUpperCase()}`; } // ?/factory/address/denom return `${this.denomType}/${CosmwasmAddress.encode(this.domain, this.address)}/${this.denom}`; } // contract or account address return CosmwasmAddress.encode(this.domain, this.address); } toNative() { return this; } toUint8Array() { return this.address; } toUniversalAddress() { const buff = new Uint8Array(sdk_connect_1.UniversalAddress.byteSize); buff.set(this.address, sdk_connect_1.UniversalAddress.byteSize - this.address.length); return new sdk_connect_1.UniversalAddress(buff); } setChain(chain) { // @ts-expect-error -- readonly this.domain = constants_js_1.chainToAddressPrefix.get(chain); } static isValidAddress(address) { try { const maybe = sdk_connect_1.encoding.bech32.decodeToBytes(address); return CosmwasmAddress.validAddressLength(maybe.bytes); } catch { } return false; } static encode(prefix, address) { return sdk_connect_1.encoding.bech32.encode(prefix, sdk_connect_1.encoding.bech32.toWords(address)); } static validAddressLength(address) { if (address.length !== CosmwasmAddress.contractAddressByteSize && address.length !== CosmwasmAddress.accountAddressByteSize) throw new Error(`Invalid Cosmwasm address, expected ${CosmwasmAddress.contractAddressByteSize} ` + `or ${CosmwasmAddress.accountAddressByteSize} bytes but got ${address.length}`); return true; } static instanceof(address) { return address.constructor.platform === CosmwasmAddress.platform; } equals(other) { if (CosmwasmAddress.instanceof(other)) { return this.toString() === other.toString(); } else { return other.equals(this.toUniversalAddress()); } } } exports.CosmwasmAddress = CosmwasmAddress; (0, sdk_connect_1.registerNative)(types_js_1._platform, CosmwasmAddress); //# sourceMappingURL=address.js.map