@wormhole-foundation/sdk-sui
Version:
SDK for Sui chains, used in conjunction with @wormhole-foundation/sdk
116 lines • 4.22 kB
JavaScript
import { normalizeSuiAddress } from "@mysten/sui/utils";
import { UniversalAddress, encoding, registerNative } from "@wormhole-foundation/sdk-connect";
import { SUI_COIN, SUI_SEPARATOR } from "./constants.js";
export const SuiZeroAddress = "0x";
export const isValidSuiType = (str) => /^(0x)?[0-9a-fA-F]+::\w+::\w+$/.test(str);
// Removes leading 0s from the address
export const trimSuiType = (type) => type.replace(/(0x)(0*)/g, "0x");
// Adds leading 0s to the address to make it 32 bytes long
export function zpadSuiAddress(address) {
address = address.startsWith("0x") ? address.slice(2) : address;
address = address.length % 2 === 0 ? address : "0" + address;
const zpadded = address.length === 64
? address
: encoding.hex.encode(encoding.bytes.zpad(encoding.hex.decode(address), 32));
return `0x${zpadded}`;
}
export const normalizeSuiType = (type) => {
const tokens = type.split(SUI_SEPARATOR);
if (tokens.length !== 3)
throw new Error(`Invalid Sui type: ${type}`);
return [normalizeSuiAddress(tokens[0]), tokens[1], tokens[2]].join(SUI_SEPARATOR);
};
export const getCoinTypeFromPackageId = (packageId) => {
return new SuiAddress(packageId).getCoinType();
};
export const getPackageIdFromType = (type) => {
return new SuiAddress(type).getPackageId();
};
export const getTableKeyType = (tableType) => {
const match = trimSuiType(tableType).match(/0x2::table::Table<(.*)>/);
if (!match)
throw new Error(`Invalid table type: ${tableType}`);
if (match.length < 2)
throw new Error(`Invalid table type: ${tableType}`);
const [keyType] = match[1].split(",");
if (!keyType || !isValidSuiType(keyType))
throw new Error(`Invalid key type: ${keyType}`);
return keyType;
};
export class SuiAddress {
static byteSize = 32;
static platform = "Sui";
// Full 32 bytes of Address
address;
// Optional module and contract name
module;
constructor(address) {
if (SuiAddress.instanceof(address)) {
this.address = address.address;
this.module = address.module;
}
else if (UniversalAddress.instanceof(address)) {
this.address = address.toUint8Array();
}
else if (typeof address === "string") {
// If we've got an address of the form `0x1234...::module::...` then
// stuff anything after the first `::` into the module field
// and continue processing the address
if (isValidSuiType(address)) {
const chunks = address.split(SUI_SEPARATOR);
this.module = chunks.slice(1).join(SUI_SEPARATOR);
address = chunks[0];
}
address = zpadSuiAddress(address);
if (!encoding.hex.valid(address))
throw new Error("Invalid Sui address: " + address);
this.address = encoding.hex.decode(address);
}
else {
this.address = address;
}
}
unwrap() {
const packageId = this.getPackageId();
const module = this.module ? SUI_SEPARATOR + this.module : "";
return `${packageId}${module}`;
}
toString() {
return this.unwrap();
}
toNative() {
return this;
}
toUint8Array() {
return this.address;
}
toUniversalAddress() {
return new UniversalAddress(this.toUint8Array());
}
getPackageId() {
return zpadSuiAddress(encoding.hex.encode(this.address));
}
getCoinType() {
// Special case for the native gas coin
if (this.module === "sui::SUI") {
return SUI_COIN;
}
if (!this.module) {
throw new Error("No module present in Sui token address");
}
return this.unwrap();
}
static instanceof(address) {
return address.constructor.platform === SuiAddress.platform;
}
equals(other) {
if (SuiAddress.instanceof(other)) {
return other.unwrap() === this.unwrap();
}
else {
return this.toUniversalAddress().equals(other);
}
}
}
registerNative("Sui", SuiAddress);
//# sourceMappingURL=address.js.map