@wormhole-foundation/sdk-sui-ntt 6.2.0 → 7.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/ntt.d.ts +9 -6
- package/dist/esm/ntt.d.ts.map +1 -1
- package/dist/esm/ntt.js +122 -167
- package/dist/esm/ntt.js.map +1 -1
- package/dist/esm/nttWithExecutor.d.ts +4 -4
- package/dist/esm/nttWithExecutor.d.ts.map +1 -1
- package/dist/esm/nttWithExecutor.js +1 -1
- package/dist/esm/nttWithExecutor.js.map +1 -1
- package/dist/esm/utils.d.ts +22 -12
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +106 -63
- package/dist/esm/utils.js.map +1 -1
- package/package.json +15 -22
- package/dist/cjs/bcs-types.d.ts +0 -36
- package/dist/cjs/bcs-types.d.ts.map +0 -1
- package/dist/cjs/bcs-types.js +0 -39
- package/dist/cjs/bcs-types.js.map +0 -1
- package/dist/cjs/constants.d.ts +0 -15
- package/dist/cjs/constants.d.ts.map +0 -1
- package/dist/cjs/constants.js +0 -21
- package/dist/cjs/constants.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -5
- package/dist/cjs/index.d.ts.map +0 -1
- package/dist/cjs/index.js +0 -35
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/ntt.d.ts +0 -66
- package/dist/cjs/ntt.d.ts.map +0 -1
- package/dist/cjs/ntt.js +0 -1277
- package/dist/cjs/ntt.js.map +0 -1
- package/dist/cjs/nttWithExecutor.d.ts +0 -30
- package/dist/cjs/nttWithExecutor.d.ts.map +0 -1
- package/dist/cjs/nttWithExecutor.js +0 -294
- package/dist/cjs/nttWithExecutor.js.map +0 -1
- package/dist/cjs/package.json +0 -1
- package/dist/cjs/utils.d.ts +0 -109
- package/dist/cjs/utils.d.ts.map +0 -1
- package/dist/cjs/utils.js +0 -312
- package/dist/cjs/utils.js.map +0 -1
package/dist/esm/ntt.d.ts
CHANGED
|
@@ -2,28 +2,30 @@ import { AccountAddress, ChainAddress, UnsignedTransaction, Contracts, ChainsCon
|
|
|
2
2
|
import type { Chain, Network } from "@wormhole-foundation/sdk-base";
|
|
3
3
|
import { Ntt, NttTransceiver } from "@wormhole-foundation/sdk-definitions-ntt";
|
|
4
4
|
import { SuiChains, SuiPlatformType } from "@wormhole-foundation/sdk-sui";
|
|
5
|
-
import {
|
|
5
|
+
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
6
6
|
export declare class SuiNtt<N extends Network, C extends SuiChains> implements Ntt<N, C> {
|
|
7
7
|
readonly contracts: Contracts & {
|
|
8
8
|
ntt?: Ntt.Contracts;
|
|
9
9
|
};
|
|
10
10
|
readonly coreBridgeStateId: string;
|
|
11
|
-
static extractTokenTypeFromSuiState(provider:
|
|
11
|
+
static extractTokenTypeFromSuiState(provider: SuiGrpcClient, stateObjectId: string): Promise<string>;
|
|
12
12
|
private getNttState;
|
|
13
13
|
readonly network: N;
|
|
14
14
|
readonly chain: C;
|
|
15
|
-
readonly provider:
|
|
15
|
+
readonly provider: SuiGrpcClient;
|
|
16
16
|
private adminCapId?;
|
|
17
17
|
private packageId?;
|
|
18
|
-
|
|
18
|
+
private nttCommonPackageId?;
|
|
19
|
+
constructor(network: N, chain: C, provider: SuiGrpcClient, contracts: Contracts & {
|
|
19
20
|
ntt?: Ntt.Contracts;
|
|
20
21
|
});
|
|
21
|
-
static fromRpc<N extends Network>(provider:
|
|
22
|
+
static fromRpc<N extends Network>(provider: SuiGrpcClient, config: ChainsConfig<N, SuiPlatformType>): Promise<SuiNtt<N, SuiChains>>;
|
|
22
23
|
getMode(): Promise<Ntt.Mode>;
|
|
23
24
|
isPaused(): Promise<boolean>;
|
|
24
25
|
getAdminCapId(): Promise<string>;
|
|
25
26
|
getPackageId(): Promise<string>;
|
|
26
27
|
getPackageIdFromObject(objectId: string): Promise<string>;
|
|
28
|
+
private getNttCommonPackageId;
|
|
27
29
|
getOwner(): Promise<AccountAddress<C>>;
|
|
28
30
|
getPauser(): Promise<AccountAddress<C> | null>;
|
|
29
31
|
getThreshold(): Promise<number>;
|
|
@@ -36,11 +38,12 @@ export declare class SuiNtt<N extends Network, C extends SuiChains> implements N
|
|
|
36
38
|
setPauser(newPauser: AccountAddress<C>, payer?: AccountAddress<C>): AsyncGenerator<UnsignedTransaction<N, C>>;
|
|
37
39
|
setPeer(peer: ChainAddress, tokenDecimals: number, inboundLimit: bigint, payer?: AccountAddress<C>): AsyncGenerator<UnsignedTransaction<N, C>>;
|
|
38
40
|
getPeer<PC extends Chain>(chain: PC): Promise<Ntt.Peer<PC> | null>;
|
|
41
|
+
private getPeerValue;
|
|
39
42
|
setTransceiverPeer(ix: number, peer: ChainAddress, payer?: AccountAddress<C>): AsyncGenerator<UnsignedTransaction<N, C>>;
|
|
40
43
|
transfer(sender: AccountAddress<C>, amount: bigint, destination: ChainAddress, options: Ntt.TransferOptions): AsyncGenerator<UnsignedTransaction<N, C>>;
|
|
41
44
|
redeem(attestations: Ntt.Attestation[], payer?: AccountAddress<C>): AsyncGenerator<UnsignedTransaction<N, C>>;
|
|
42
|
-
quoteDeliveryPrice(destination: Chain, options: Ntt.TransferOptions): Promise<bigint>;
|
|
43
45
|
isRelayingAvailable(destination: Chain): Promise<boolean>;
|
|
46
|
+
quoteDeliveryPrice(destination: Chain, options: Ntt.TransferOptions): Promise<bigint>;
|
|
44
47
|
getCurrentOutboundCapacity(): Promise<bigint>;
|
|
45
48
|
getOutboundLimit(): Promise<bigint>;
|
|
46
49
|
setOutboundLimit(limit: bigint, payer?: AccountAddress<C>): AsyncGenerator<UnsignedTransaction<N, C>>;
|
package/dist/esm/ntt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ntt.d.ts","sourceRoot":"","sources":["../../src/ntt.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,mBAAmB,EAEnB,SAAS,EACT,YAAY,EAEb,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,EACL,GAAG,EACH,cAAc,EAEf,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAEL,SAAS,EAET,eAAe,EAEhB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ntt.d.ts","sourceRoot":"","sources":["../../src/ntt.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,mBAAmB,EAEnB,SAAS,EACT,YAAY,EAEb,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,EACL,GAAG,EACH,cAAc,EAEf,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAEL,SAAS,EAET,eAAe,EAEhB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAoEjD,qBAAa,MAAM,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,SAAS,CACxD,YAAW,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IA6DlB,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG;QAAE,GAAG,CAAC,EAAE,GAAG,CAAC,SAAS,CAAA;KAAE;IA3DzD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;WAEtB,4BAA4B,CACvC,QAAQ,EAAE,aAAa,EACvB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC;YA0BJ,WAAW;IAiBzB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAS;gBAGlC,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,aAAa,EACd,SAAS,EAAE,SAAS,GAAG;QAAE,GAAG,CAAC,EAAE,GAAG,CAAC,SAAS,CAAA;KAAE;WAiB5C,OAAO,CAAC,CAAC,SAAS,OAAO,EACpC,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,YAAY,CAAC,CAAC,EAAE,eAAe,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAkB1B,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAc5B,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAK5B,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAchC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAa/B,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAOjD,qBAAqB;IAY7B,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IA+BtC,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAK9C,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAK9B,YAAY,CACjB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA2BtC,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAcnC,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAOnC,KAAK,IAAI,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA0BlD,OAAO,IAAI,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA0BpD,QAAQ,CACb,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,EAC3B,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAuBrC,SAAS,CACd,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,EAC5B,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IASrC,OAAO,CACZ,IAAI,EAAE,YAAY,EAClB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA4DtC,OAAO,CAAC,EAAE,SAAS,KAAK,EAAE,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;YA0C1D,YAAY;IAmCnB,kBAAkB,CACvB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,YAAY,EAClB,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA4GrC,QAAQ,CACb,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EACzB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,YAAY,EACzB,OAAO,EAAE,GAAG,CAAC,eAAe,GAC3B,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA+MrC,MAAM,CACX,YAAY,EAAE,GAAG,CAAC,WAAW,EAAE,EAC/B,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAuCtC,mBAAmB,CAAC,WAAW,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzD,kBAAkB,CACtB,WAAW,EAAE,KAAK,EAClB,OAAO,EAAE,GAAG,CAAC,eAAe,GAC3B,OAAO,CAAC,MAAM,CAAC;IAKZ,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC;IA6B7C,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAalC,gBAAgB,CACrB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAkCtC,yBAAyB,CAAC,EAAE,SAAS,KAAK,EAC9C,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,MAAM,CAAC;IA0CZ,eAAe,CAAC,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAYhE,eAAe,CAAC,EAAE,SAAS,KAAK,EACrC,SAAS,EAAE,EAAE,EACb,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA0EtC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAMvC,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAuB7D,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAO7D,0BAA0B,CAC9B,WAAW,EAAE,GAAG,CAAC,WAAW,GAC3B,OAAO,CAAC,OAAO,CAAC;IAOb,wBAAwB,CAAC,EAAE,SAAS,KAAK,EAC7C,SAAS,EAAE,EAAE,EACb,kBAAkB,EAAE,GAAG,CAAC,OAAO,GAC9B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAsExC,6BAA6B,CAAC,EAAE,SAAS,KAAK,EACnD,SAAS,EAAE,EAAE,EACb,kBAAkB,EAAE,GAAG,CAAC,OAAO,EAC/B,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAqBtC,cAAc,CAClB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IAsDlD,kBAAkB,CAAC,EAAE,SAAS,KAAK,EACvC,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,EAAE,GACd,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAsD7B,kBAAkB,CAAC,gBAAgB,GAAE,MAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAgDjE,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IA6FzD,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;YAQ1B,cAAc;YA6Ed,aAAa;YAiFb,wBAAwB;YAaxB,YAAY;CA+F3B"}
|
package/dist/esm/ntt.js
CHANGED
|
@@ -4,23 +4,23 @@ import { nativeTokenTransferLayout, } from "@wormhole-foundation/sdk-definitions
|
|
|
4
4
|
import { SuiAddress, SuiPlatform, SuiUnsignedTransaction, } from "@wormhole-foundation/sdk-sui";
|
|
5
5
|
import { Transaction } from "@mysten/sui/transactions";
|
|
6
6
|
import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils";
|
|
7
|
+
import { bcs, fromBase64 } from "@mysten/bcs";
|
|
7
8
|
import { SUI_ADDRESSES, RATE_LIMIT_DURATION } from "./constants.js";
|
|
8
|
-
import { isNativeToken, getSuiObject, getWormholePackageId, getPackageIdFromObject, countSetBits,
|
|
9
|
+
import { isNativeToken, getSuiObject, getWormholePackageId, getPackageIdFromObject, countSetBits, getNttCommonPackageId, createNttManagerMessageObjects, parseInboxItemResult, getCoinMetadataId, } from "./utils.js";
|
|
9
10
|
export class SuiNtt {
|
|
10
11
|
contracts;
|
|
11
12
|
coreBridgeStateId;
|
|
12
13
|
// Helper function to extract token type from Sui state object
|
|
13
14
|
static async extractTokenTypeFromSuiState(provider, stateObjectId) {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
options: { showType: true },
|
|
15
|
+
const { object } = await provider.getObject({
|
|
16
|
+
objectId: stateObjectId,
|
|
17
17
|
});
|
|
18
|
-
if (!
|
|
18
|
+
if (!object?.type) {
|
|
19
19
|
throw new Error("Failed to fetch state object type");
|
|
20
20
|
}
|
|
21
21
|
// Parse the generic type parameter from the state object type
|
|
22
22
|
// Format: "packageId::ntt::State<TokenType>"
|
|
23
|
-
const objectType =
|
|
23
|
+
const objectType = object.type;
|
|
24
24
|
const genericStart = objectType.indexOf("<");
|
|
25
25
|
const genericEnd = objectType.lastIndexOf(">");
|
|
26
26
|
if (genericStart === -1 || genericEnd === -1) {
|
|
@@ -44,6 +44,7 @@ export class SuiNtt {
|
|
|
44
44
|
provider;
|
|
45
45
|
adminCapId; // Cached NTT AdminCap object ID
|
|
46
46
|
packageId; // Cached NTT package ID for move calls
|
|
47
|
+
nttCommonPackageId; // Cached ntt-common package ID
|
|
47
48
|
constructor(network, chain, provider, contracts) {
|
|
48
49
|
this.contracts = contracts;
|
|
49
50
|
if (!contracts.ntt) {
|
|
@@ -112,33 +113,34 @@ export class SuiNtt {
|
|
|
112
113
|
const result = await getPackageIdFromObject(this.provider, objectId);
|
|
113
114
|
return result.current;
|
|
114
115
|
}
|
|
116
|
+
// Derives (and caches) the ntt-common package id from the NTT State object.
|
|
117
|
+
async getNttCommonPackageId() {
|
|
118
|
+
if (this.nttCommonPackageId) {
|
|
119
|
+
return this.nttCommonPackageId;
|
|
120
|
+
}
|
|
121
|
+
this.nttCommonPackageId = await getNttCommonPackageId(this.provider, this.contracts.ntt["manager"]);
|
|
122
|
+
return this.nttCommonPackageId;
|
|
123
|
+
}
|
|
115
124
|
async getOwner() {
|
|
116
125
|
const adminCapId = await this.getAdminCapId();
|
|
117
126
|
try {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
options: {
|
|
121
|
-
showOwner: true,
|
|
122
|
-
},
|
|
127
|
+
const { object } = await this.provider.getObject({
|
|
128
|
+
objectId: adminCapId,
|
|
123
129
|
});
|
|
124
|
-
|
|
130
|
+
const owner = object?.owner;
|
|
131
|
+
if (!owner) {
|
|
125
132
|
throw new Error("Could not fetch AdminCap owner information");
|
|
126
133
|
}
|
|
127
|
-
// Extract owner address from the owner
|
|
134
|
+
// Extract owner address from the owner discriminated union
|
|
128
135
|
let ownerAddress;
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
ownerAddress = adminCap.data.owner.AddressOwner;
|
|
132
|
-
}
|
|
133
|
-
else if (typeof adminCap.data.owner === "object" &&
|
|
134
|
-
"ObjectOwner" in adminCap.data.owner) {
|
|
135
|
-
ownerAddress = adminCap.data.owner.ObjectOwner;
|
|
136
|
+
if (owner.$kind === "AddressOwner") {
|
|
137
|
+
ownerAddress = owner.AddressOwner;
|
|
136
138
|
}
|
|
137
|
-
else if (
|
|
138
|
-
ownerAddress =
|
|
139
|
+
else if (owner.$kind === "ObjectOwner") {
|
|
140
|
+
ownerAddress = owner.ObjectOwner;
|
|
139
141
|
}
|
|
140
142
|
else {
|
|
141
|
-
throw new Error(`AdminCap has unexpected owner type: ${JSON.stringify(
|
|
143
|
+
throw new Error(`AdminCap has unexpected owner type: ${JSON.stringify(owner)}`);
|
|
142
144
|
}
|
|
143
145
|
return ownerAddress;
|
|
144
146
|
}
|
|
@@ -172,7 +174,7 @@ export class SuiNtt {
|
|
|
172
174
|
yield unsignedTx;
|
|
173
175
|
}
|
|
174
176
|
async getTokenDecimals() {
|
|
175
|
-
const coinMetadata = await this.provider.getCoinMetadata({
|
|
177
|
+
const { coinMetadata } = await this.provider.getCoinMetadata({
|
|
176
178
|
coinType: this.contracts.ntt["token"],
|
|
177
179
|
});
|
|
178
180
|
if (!coinMetadata?.decimals) {
|
|
@@ -275,41 +277,19 @@ export class SuiNtt {
|
|
|
275
277
|
yield unsignedTx;
|
|
276
278
|
}
|
|
277
279
|
async getPeer(chain) {
|
|
278
|
-
const state = await this.
|
|
279
|
-
|
|
280
|
-
options: {
|
|
281
|
-
showContent: true,
|
|
282
|
-
},
|
|
283
|
-
});
|
|
284
|
-
if (!state.data?.content || state.data.content.dataType !== "moveObject") {
|
|
285
|
-
throw new Error("Failed to fetch NTT state object");
|
|
286
|
-
}
|
|
287
|
-
const fields = state.data.content.fields;
|
|
288
|
-
const peersTable = fields.peers;
|
|
280
|
+
const state = await this.getNttState();
|
|
281
|
+
const peersTable = state.peers;
|
|
289
282
|
// Convert chain name to chain ID and look up in peers table
|
|
290
283
|
const chainId = chainToChainId(chain);
|
|
291
284
|
try {
|
|
292
|
-
//
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
name: {
|
|
296
|
-
type: "u16",
|
|
297
|
-
value: chainId,
|
|
298
|
-
},
|
|
299
|
-
});
|
|
300
|
-
if (!peerField.data?.content ||
|
|
301
|
-
peerField.data.content.dataType !== "moveObject") {
|
|
285
|
+
// Read the peer value (flat json) from the peers table dynamic field
|
|
286
|
+
const peerData = await this.getPeerValue(peersTable.id, chainId);
|
|
287
|
+
if (!peerData) {
|
|
302
288
|
// Peer not found for this chain
|
|
303
289
|
return null;
|
|
304
290
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
// Extract address bytes from ExternalAddress
|
|
308
|
-
const externalAddress = peerData.address;
|
|
309
|
-
const addressBytes = externalAddress.fields.value.fields.data;
|
|
310
|
-
// Convert address bytes to ChainAddress
|
|
311
|
-
// The address bytes are stored as a vector of u8, we need to convert to the appropriate format
|
|
312
|
-
const addressUint8Array = new Uint8Array(addressBytes);
|
|
291
|
+
// Extract address bytes from ExternalAddress (vector<u8> as base64)
|
|
292
|
+
const addressUint8Array = fromBase64(peerData.address.value.data);
|
|
313
293
|
const chainAddress = {
|
|
314
294
|
chain: chain,
|
|
315
295
|
address: toUniversal(chain, addressUint8Array),
|
|
@@ -317,8 +297,7 @@ export class SuiNtt {
|
|
|
317
297
|
// Extract token decimals
|
|
318
298
|
const tokenDecimals = parseInt(peerData.token_decimals, 10);
|
|
319
299
|
// Extract inbound limit from rate limit state
|
|
320
|
-
const
|
|
321
|
-
const inboundLimit = BigInt(inboundRateLimit.limit);
|
|
300
|
+
const inboundLimit = BigInt(peerData.inbound_rate_limit.limit);
|
|
322
301
|
return {
|
|
323
302
|
address: chainAddress,
|
|
324
303
|
tokenDecimals: tokenDecimals,
|
|
@@ -331,6 +310,36 @@ export class SuiNtt {
|
|
|
331
310
|
return null;
|
|
332
311
|
}
|
|
333
312
|
}
|
|
313
|
+
// Reads the flat-json `value` struct of a peers-table dynamic field keyed by
|
|
314
|
+
// a u16 chain id. Returns null when the field does not exist.
|
|
315
|
+
async getPeerValue(parentId, chainId) {
|
|
316
|
+
let dynamicField;
|
|
317
|
+
try {
|
|
318
|
+
const result = await this.provider.getDynamicField({
|
|
319
|
+
parentId,
|
|
320
|
+
name: {
|
|
321
|
+
type: "u16",
|
|
322
|
+
bcs: bcs.u16().serialize(chainId).toBytes(),
|
|
323
|
+
},
|
|
324
|
+
});
|
|
325
|
+
dynamicField = result.dynamicField;
|
|
326
|
+
}
|
|
327
|
+
catch (e) {
|
|
328
|
+
// The real client throws when the field does not exist.
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
if (!dynamicField?.fieldId) {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
const { object } = await this.provider.getObject({
|
|
335
|
+
objectId: dynamicField.fieldId,
|
|
336
|
+
include: { json: true },
|
|
337
|
+
});
|
|
338
|
+
if (!object?.json) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
return object.json.value ?? null;
|
|
342
|
+
}
|
|
334
343
|
async *setTransceiverPeer(ix, peer, payer) {
|
|
335
344
|
// For now, only support index 0 which is the wormhole transceiver
|
|
336
345
|
if (ix !== 0) {
|
|
@@ -580,18 +589,17 @@ export class SuiNtt {
|
|
|
580
589
|
const unsignedTx = new SuiUnsignedTransaction(txb, this.network, this.chain, "Redeem NTT Transfer");
|
|
581
590
|
yield unsignedTx;
|
|
582
591
|
}
|
|
583
|
-
async quoteDeliveryPrice(destination, options) {
|
|
584
|
-
throw new Error("Not implemented");
|
|
585
|
-
}
|
|
586
592
|
async isRelayingAvailable(destination) {
|
|
587
|
-
// We don't have a quoter in Sui NTT, so relaying is currently not available
|
|
588
593
|
return false;
|
|
589
594
|
}
|
|
595
|
+
async quoteDeliveryPrice(destination, options) {
|
|
596
|
+
throw new Error("Not implemented");
|
|
597
|
+
}
|
|
590
598
|
// Rate Limiting
|
|
591
599
|
async getCurrentOutboundCapacity() {
|
|
592
600
|
const state = await getSuiObject(this.provider, this.contracts.ntt["manager"], "Failed to fetch NTT state object");
|
|
593
601
|
const fields = state.fields;
|
|
594
|
-
const outboxRateLimit = fields.outbox.
|
|
602
|
+
const outboxRateLimit = fields.outbox.rate_limit;
|
|
595
603
|
// Get current timestamp (this would ideally come from Clock object)
|
|
596
604
|
const currentTime = Date.now();
|
|
597
605
|
// Calculate capacity using the rate limit formula
|
|
@@ -609,7 +617,7 @@ export class SuiNtt {
|
|
|
609
617
|
async getOutboundLimit() {
|
|
610
618
|
const state = await getSuiObject(this.provider, this.contracts.ntt["manager"], "Failed to fetch NTT state object");
|
|
611
619
|
const fields = state.fields;
|
|
612
|
-
const outboxRateLimit = fields.outbox.
|
|
620
|
+
const outboxRateLimit = fields.outbox.rate_limit;
|
|
613
621
|
return BigInt(outboxRateLimit.limit);
|
|
614
622
|
}
|
|
615
623
|
async *setOutboundLimit(limit, payer) {
|
|
@@ -637,36 +645,18 @@ export class SuiNtt {
|
|
|
637
645
|
yield unsignedTx;
|
|
638
646
|
}
|
|
639
647
|
async getCurrentInboundCapacity(fromChain) {
|
|
640
|
-
const state = await this.
|
|
641
|
-
|
|
642
|
-
options: {
|
|
643
|
-
showContent: true,
|
|
644
|
-
},
|
|
645
|
-
});
|
|
646
|
-
if (!state.data?.content || state.data.content.dataType !== "moveObject") {
|
|
647
|
-
throw new Error("Failed to fetch NTT state object");
|
|
648
|
-
}
|
|
649
|
-
const fields = state.data.content.fields;
|
|
650
|
-
const peersTable = fields.peers;
|
|
648
|
+
const state = await this.getNttState();
|
|
649
|
+
const peersTable = state.peers;
|
|
651
650
|
// Convert chain to wormhole chain ID
|
|
652
651
|
const chainId = chainToChainId(fromChain);
|
|
653
652
|
try {
|
|
654
|
-
//
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
name: {
|
|
658
|
-
type: "u16",
|
|
659
|
-
value: chainId,
|
|
660
|
-
},
|
|
661
|
-
});
|
|
662
|
-
if (!peerField.data?.content ||
|
|
663
|
-
peerField.data.content.dataType !== "moveObject") {
|
|
653
|
+
// Read the peer value (flat json) from the peers table dynamic field
|
|
654
|
+
const peerData = await this.getPeerValue(peersTable.id, chainId);
|
|
655
|
+
if (!peerData) {
|
|
664
656
|
throw new Error(`No peer found for chain ${fromChain}`);
|
|
665
657
|
}
|
|
666
|
-
const peerData = peerField.data.content.fields.value
|
|
667
|
-
.fields;
|
|
668
658
|
// Extract inbound rate limit state
|
|
669
|
-
const inboundRateLimit = peerData.inbound_rate_limit
|
|
659
|
+
const inboundRateLimit = peerData.inbound_rate_limit;
|
|
670
660
|
// Get current timestamp (this would ideally come from Clock object)
|
|
671
661
|
const currentTime = Date.now();
|
|
672
662
|
// Calculate capacity using the rate limit formula
|
|
@@ -871,7 +861,7 @@ export class SuiNtt {
|
|
|
871
861
|
const state = await getSuiObject(suiNtt.provider, wormholeTransceiverStateId);
|
|
872
862
|
return {
|
|
873
863
|
chain: chain,
|
|
874
|
-
address: toUniversal(chain, state.fields.emitter_cap.
|
|
864
|
+
address: toUniversal(chain, state.fields.emitter_cap.id),
|
|
875
865
|
};
|
|
876
866
|
},
|
|
877
867
|
async *setPeer(peer, payer) {
|
|
@@ -905,37 +895,26 @@ export class SuiNtt {
|
|
|
905
895
|
// chainToChainId is already imported at the top of the file
|
|
906
896
|
try {
|
|
907
897
|
// Get the transceiver state object
|
|
908
|
-
const
|
|
909
|
-
|
|
910
|
-
|
|
898
|
+
const { object } = await this.provider.getObject({
|
|
899
|
+
objectId: wormholeTransceiverStateId,
|
|
900
|
+
include: { json: true },
|
|
911
901
|
});
|
|
912
|
-
if (!
|
|
913
|
-
transceiverState.data.content.dataType !== "moveObject") {
|
|
902
|
+
if (!object?.json) {
|
|
914
903
|
return null;
|
|
915
904
|
}
|
|
916
|
-
const fields =
|
|
905
|
+
const fields = object.json;
|
|
917
906
|
const peersTable = fields.peers;
|
|
918
907
|
// Convert target chain to chain ID
|
|
919
908
|
const chainId = chainToChainId(targetChain);
|
|
920
|
-
//
|
|
921
|
-
const
|
|
922
|
-
|
|
923
|
-
name: {
|
|
924
|
-
type: "u16",
|
|
925
|
-
value: chainId,
|
|
926
|
-
},
|
|
927
|
-
});
|
|
928
|
-
if (!peerField.data?.content ||
|
|
929
|
-
peerField.data.content.dataType !== "moveObject") {
|
|
909
|
+
// Read the transceiver peer value (flat json) from the peers table
|
|
910
|
+
const peerValue = await this.getPeerValue(peersTable.id, chainId);
|
|
911
|
+
if (!peerValue) {
|
|
930
912
|
// Peer not found for this chain
|
|
931
913
|
return null;
|
|
932
914
|
}
|
|
933
|
-
//
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
const addressBytes = externalAddress.fields.value.fields.data;
|
|
937
|
-
// Convert address bytes to ChainAddress
|
|
938
|
-
const addressUint8Array = new Uint8Array(addressBytes);
|
|
915
|
+
// The transceiver peer's stored value is itself an ExternalAddress
|
|
916
|
+
// (vector<u8> as base64)
|
|
917
|
+
const addressUint8Array = fromBase64(peerValue.value.data);
|
|
939
918
|
const chainAddress = {
|
|
940
919
|
chain: targetChain,
|
|
941
920
|
address: toUniversal(targetChain, addressUint8Array),
|
|
@@ -958,43 +937,31 @@ export class SuiNtt {
|
|
|
958
937
|
throw new Error("Wormhole transceiver not found in contracts");
|
|
959
938
|
}
|
|
960
939
|
// Get the transceiver state object
|
|
961
|
-
const
|
|
962
|
-
|
|
963
|
-
options: { showType: true },
|
|
940
|
+
const { object } = await this.provider.getObject({
|
|
941
|
+
objectId: wormholeTransceiverStateId,
|
|
964
942
|
});
|
|
965
|
-
if (!
|
|
943
|
+
if (!object?.type) {
|
|
966
944
|
throw new Error("Unable to determine transceiver object type");
|
|
967
945
|
}
|
|
968
946
|
// Extract package ID from the object type
|
|
969
947
|
// Type format: "packageId::module::Type<...>"
|
|
970
|
-
const packageId =
|
|
948
|
+
const packageId = object.type.split("::")[0];
|
|
971
949
|
// Build transaction to call get_transceiver_type from the standard transceiver module
|
|
972
950
|
const tx = new Transaction();
|
|
973
951
|
tx.moveCall({
|
|
974
952
|
target: `${packageId}::transceiver::get_transceiver_type`,
|
|
975
953
|
arguments: [],
|
|
976
954
|
});
|
|
977
|
-
// Use
|
|
978
|
-
const
|
|
979
|
-
|
|
980
|
-
|
|
955
|
+
// Use simulateTransaction to call the view function
|
|
956
|
+
const { commandResults } = await this.provider.simulateTransaction({
|
|
957
|
+
transaction: tx,
|
|
958
|
+
include: { commandResults: true },
|
|
959
|
+
checksEnabled: false,
|
|
981
960
|
});
|
|
982
|
-
// Parse the response
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
const returnValue = result.returnValues[0];
|
|
987
|
-
if (returnValue &&
|
|
988
|
-
Array.isArray(returnValue) &&
|
|
989
|
-
returnValue.length > 0) {
|
|
990
|
-
// The return value should be [bytes, type] where bytes is an array of numbers
|
|
991
|
-
const bytesData = returnValue[0];
|
|
992
|
-
if (Array.isArray(bytesData)) {
|
|
993
|
-
const transceiverType = new TextDecoder().decode(new Uint8Array(bytesData));
|
|
994
|
-
return transceiverType;
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
}
|
|
961
|
+
// Parse the response: the Move fn returns an ascii String
|
|
962
|
+
const returnValue = commandResults?.[0]?.returnValues?.[0]?.bcs;
|
|
963
|
+
if (returnValue) {
|
|
964
|
+
return bcs.string().parse(new Uint8Array(returnValue));
|
|
998
965
|
}
|
|
999
966
|
throw new Error("Failed to get transceiver info from response");
|
|
1000
967
|
}
|
|
@@ -1002,20 +969,19 @@ export class SuiNtt {
|
|
|
1002
969
|
// Verify that the addresses in the contracts configuration are valid
|
|
1003
970
|
try {
|
|
1004
971
|
// Check if manager address exists and is a valid NTT state object
|
|
1005
|
-
const
|
|
1006
|
-
|
|
1007
|
-
|
|
972
|
+
const { object } = await this.provider.getObject({
|
|
973
|
+
objectId: this.contracts.ntt["manager"],
|
|
974
|
+
include: { json: true },
|
|
1008
975
|
});
|
|
1009
|
-
if (!
|
|
1010
|
-
state.data.content.dataType !== "moveObject") {
|
|
976
|
+
if (!object?.json) {
|
|
1011
977
|
return null;
|
|
1012
978
|
}
|
|
1013
|
-
const fields =
|
|
979
|
+
const fields = object.json;
|
|
1014
980
|
// Look up registered transceivers in the transceiver registry
|
|
1015
981
|
const transceiverRegistry = fields.transceivers;
|
|
1016
|
-
const registryId = transceiverRegistry.
|
|
982
|
+
const registryId = transceiverRegistry.id;
|
|
1017
983
|
// Query the registry's dynamic fields to find registered transceivers
|
|
1018
|
-
const dynamicFields = await this.provider.
|
|
984
|
+
const dynamicFields = await this.provider.listDynamicFields({
|
|
1019
985
|
parentId: registryId,
|
|
1020
986
|
});
|
|
1021
987
|
const result = {
|
|
@@ -1025,20 +991,18 @@ export class SuiNtt {
|
|
|
1025
991
|
};
|
|
1026
992
|
// For now, we only look for the wormhole transceiver at index 0
|
|
1027
993
|
// The dynamic field key structure is based on the Move code in transceiver_registry.move
|
|
1028
|
-
for (const field of dynamicFields.
|
|
994
|
+
for (const field of dynamicFields.dynamicFields) {
|
|
1029
995
|
if (field.name?.type?.includes("transceiver_registry::Key")) {
|
|
1030
996
|
// This is a transceiver registration
|
|
1031
997
|
try {
|
|
1032
|
-
const transceiverInfo = await this.provider.getObject({
|
|
1033
|
-
|
|
1034
|
-
|
|
998
|
+
const { object: transceiverInfo } = await this.provider.getObject({
|
|
999
|
+
objectId: field.fieldId,
|
|
1000
|
+
include: { json: true },
|
|
1035
1001
|
});
|
|
1036
|
-
if (transceiverInfo
|
|
1037
|
-
transceiverInfo.
|
|
1038
|
-
const infoFields = transceiverInfo.data.content
|
|
1039
|
-
.fields.value.fields;
|
|
1002
|
+
if (transceiverInfo?.json) {
|
|
1003
|
+
const infoFields = transceiverInfo.json.value;
|
|
1040
1004
|
const transceiverStateId = infoFields.state_object_id;
|
|
1041
|
-
const transceiverIndex = infoFields.id;
|
|
1005
|
+
const transceiverIndex = Number(infoFields.id);
|
|
1042
1006
|
// For index 0, assume it's the wormhole transceiver
|
|
1043
1007
|
if (transceiverIndex === 0) {
|
|
1044
1008
|
result.transceiver["wormhole"] = transceiverStateId;
|
|
@@ -1093,18 +1057,6 @@ export class SuiNtt {
|
|
|
1093
1057
|
if (!wormholeAttestation) {
|
|
1094
1058
|
throw new Error("No wormhole attestation found");
|
|
1095
1059
|
}
|
|
1096
|
-
// Get manager state to extract nttCommonPackageId
|
|
1097
|
-
const managerState = await this.provider.getObject({
|
|
1098
|
-
id: this.contracts.ntt["manager"],
|
|
1099
|
-
options: { showContent: true },
|
|
1100
|
-
});
|
|
1101
|
-
if (!managerState.data?.content ||
|
|
1102
|
-
managerState.data.content.dataType !== "moveObject") {
|
|
1103
|
-
throw new Error("Failed to fetch manager state");
|
|
1104
|
-
}
|
|
1105
|
-
const managerStateObject = managerState.data.content;
|
|
1106
|
-
// Extract nttCommonPackageId from manager object's inbox type
|
|
1107
|
-
const nttCommonPackageId = extractNttCommonPackageId(managerStateObject.fields.inbox.type);
|
|
1108
1060
|
// Get manager payload
|
|
1109
1061
|
const nttPayload = wormholeAttestation.payload.nttManagerPayload;
|
|
1110
1062
|
// Get NTT object
|
|
@@ -1116,6 +1068,8 @@ export class SuiNtt {
|
|
|
1116
1068
|
catch (error) {
|
|
1117
1069
|
throw new Error(`Failed to serialize native token transfer payload: ${error instanceof Error ? error.message : String(error)}`);
|
|
1118
1070
|
}
|
|
1071
|
+
// Derive the ntt-common package id from the manager state object
|
|
1072
|
+
const nttCommonPackageId = await this.getNttCommonPackageId();
|
|
1119
1073
|
const wormholeCoreBridgePackageId = await getWormholePackageId(this.provider, this.coreBridgeStateId);
|
|
1120
1074
|
// Create the NttManagerMessage object using the utility function
|
|
1121
1075
|
const manager_message = createNttManagerMessageObjects(txb, nttCommonPackageId, wormholeCoreBridgePackageId, payloadBytes, nttPayload.id, nttPayload.sender.toUint8Array());
|
|
@@ -1213,7 +1167,7 @@ export class SuiNtt {
|
|
|
1213
1167
|
async getInboxItem(attestation) {
|
|
1214
1168
|
const nttState = await this.getNttState();
|
|
1215
1169
|
const threshold = parseInt(nttState.threshold);
|
|
1216
|
-
const nttCommonPackageId =
|
|
1170
|
+
const nttCommonPackageId = await this.getNttCommonPackageId();
|
|
1217
1171
|
// Get the coin type from the contracts configuration
|
|
1218
1172
|
const coinType = this.contracts.ntt["token"];
|
|
1219
1173
|
// Get chain ID
|
|
@@ -1261,10 +1215,11 @@ export class SuiNtt {
|
|
|
1261
1215
|
],
|
|
1262
1216
|
arguments: [inboxItemRef],
|
|
1263
1217
|
});
|
|
1264
|
-
// Execute the transaction in
|
|
1265
|
-
const inspectResult = await this.provider.
|
|
1266
|
-
|
|
1267
|
-
|
|
1218
|
+
// Execute the transaction in simulate mode to read the result
|
|
1219
|
+
const inspectResult = await this.provider.simulateTransaction({
|
|
1220
|
+
transaction: txb,
|
|
1221
|
+
include: { commandResults: true },
|
|
1222
|
+
checksEnabled: false,
|
|
1268
1223
|
});
|
|
1269
1224
|
// Parse and return the result
|
|
1270
1225
|
return parseInboxItemResult(inspectResult, threshold);
|