Skip to content

Commit 37aa8a0

Browse files
committed
feat(contract_manager): support near wormhole contract and upgrade payload
1 parent 5cbab9e commit 37aa8a0

File tree

5 files changed

+137
-33
lines changed

5 files changed

+137
-33
lines changed

contract_manager/src/chains.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,8 +898,12 @@ export class NearChain extends Chain {
898898
};
899899
}
900900

901-
generateGovernanceUpgradePayload(upgradeInfo: unknown): Buffer {
902-
throw new Error("unsupported");
901+
/**
902+
* Returns the payload for a governance contract upgrade instruction for contracts deployed on this chain
903+
* @param codeHash hex string of the 32 byte code hash for the new contract without the 0x prefix
904+
*/
905+
generateGovernanceUpgradePayload(codeHash: string): Buffer {
906+
return new UpgradeContract256Bit(this.wormholeChainName, codeHash).encode();
903907
}
904908

905909
async getAccountAddress(privateKey: PrivateKey): Promise<string> {

contract_manager/src/contracts/near.ts

Lines changed: 122 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,82 @@ import {
88
} from "../base";
99
import { Chain, NearChain } from "../chains";
1010
import * as nearAPI from "near-api-js";
11-
import * as bs58 from "bs58";
1211
import { BN } from "fuels";
12+
import { WormholeContract } from "./wormhole";
13+
14+
export class NearWormholeContract extends WormholeContract {
15+
static type = "NearWormholeContract";
16+
17+
constructor(public chain: NearChain, public address: string) {
18+
super();
19+
}
20+
21+
getId(): string {
22+
return `${this.chain.getId()}__${this.address.replace(/-|\./g, "_")}`;
23+
}
24+
25+
getChain(): NearChain {
26+
return this.chain;
27+
}
28+
29+
getType(): string {
30+
return NearWormholeContract.type;
31+
}
32+
33+
static fromJson(
34+
chain: Chain,
35+
parsed: { type: string; address: string }
36+
): NearWormholeContract {
37+
if (parsed.type !== NearWormholeContract.type)
38+
throw new Error("Invalid type");
39+
if (!(chain instanceof NearChain))
40+
throw new Error(`Wrong chain type ${chain}`);
41+
return new NearWormholeContract(chain, parsed.address);
42+
}
43+
44+
toJson(): KeyValueConfig {
45+
return {
46+
chain: this.chain.getId(),
47+
address: this.address,
48+
type: NearWormholeContract.type,
49+
};
50+
}
51+
52+
async upgradeGuardianSets(
53+
senderPrivateKey: PrivateKey,
54+
vaa: Buffer
55+
): Promise<TxResult> {
56+
const senderAddress = await this.chain.getAccountAddress(senderPrivateKey);
57+
const account = await this.chain.getNearAccount(
58+
senderAddress,
59+
senderPrivateKey
60+
);
61+
const outcome = await account.functionCall({
62+
contractId: this.address,
63+
methodName: "submit_vaa",
64+
args: { vaa: vaa.toString("hex") },
65+
gas: new BN(300e12),
66+
attachedDeposit: new BN(1e12),
67+
});
68+
return { id: outcome.transaction.hash, info: outcome };
69+
}
70+
71+
getCurrentGuardianSetIndex(): Promise<number> {
72+
throw new Error(
73+
"near wormhole contract doesn't implement getCurrentGuardianSetIndex method"
74+
);
75+
}
76+
getChainId(): Promise<number> {
77+
throw new Error(
78+
"near wormhole contract doesn't implement getChainId method"
79+
);
80+
}
81+
getGuardianSet(): Promise<string[]> {
82+
throw new Error(
83+
"near wormhole contract doesn't implement getGuardianSet method"
84+
);
85+
}
86+
}
1387

1488
export class NearPriceFeedContract extends PriceFeedContract {
1589
public static type = "NearPriceFeedContract";
@@ -18,6 +92,26 @@ export class NearPriceFeedContract extends PriceFeedContract {
1892
super();
1993
}
2094

95+
getId(): string {
96+
return `${this.chain.getId()}__${this.address.replace(/-|\./g, "_")}`;
97+
}
98+
99+
getType(): string {
100+
return NearPriceFeedContract.type;
101+
}
102+
103+
getChain(): NearChain {
104+
return this.chain;
105+
}
106+
107+
toJson(): KeyValueConfig {
108+
return {
109+
chain: this.chain.getId(),
110+
address: this.address,
111+
type: NearPriceFeedContract.type,
112+
};
113+
}
114+
21115
static fromJson(
22116
chain: Chain,
23117
parsed: { type: string; address: string }
@@ -31,10 +125,6 @@ export class NearPriceFeedContract extends PriceFeedContract {
31125
return new NearPriceFeedContract(chain, parsed.address);
32126
}
33127

34-
getChain(): NearChain {
35-
return this.chain;
36-
}
37-
38128
async getContractNearAccount(
39129
senderPrivateKey?: PrivateKey
40130
): Promise<nearAPI.Account> {
@@ -113,8 +203,11 @@ export class NearPriceFeedContract extends PriceFeedContract {
113203
if (vaas.length === 0) {
114204
throw new Error("no vaas specified");
115205
}
116-
const address = await this.chain.getAccountAddress(senderPrivateKey);
117-
const account = await this.chain.getNearAccount(address, senderPrivateKey);
206+
const senderAddress = await this.chain.getAccountAddress(senderPrivateKey);
207+
const account = await this.chain.getNearAccount(
208+
senderAddress,
209+
senderPrivateKey
210+
);
118211
let results = [];
119212
for (let vaa of vaas) {
120213
const outcome = await account.functionCall({
@@ -124,7 +217,6 @@ export class NearPriceFeedContract extends PriceFeedContract {
124217
gas: new BN(300e12),
125218
attachedDeposit: new BN(1e12),
126219
});
127-
console.log("outcome", outcome);
128220
results.push({ id: outcome.transaction.hash, info: outcome });
129221
}
130222
if (results.length === 1) {
@@ -137,6 +229,25 @@ export class NearPriceFeedContract extends PriceFeedContract {
137229
}
138230
}
139231

232+
async executeGovernanceInstruction(
233+
senderPrivateKey: PrivateKey,
234+
vaa: Buffer
235+
): Promise<TxResult> {
236+
const senderAddress = await this.chain.getAccountAddress(senderPrivateKey);
237+
const account = await this.chain.getNearAccount(
238+
senderAddress,
239+
senderPrivateKey
240+
);
241+
const outcome = await account.functionCall({
242+
contractId: this.address,
243+
methodName: "execute_governance_instruction",
244+
args: { vaa: vaa.toString("hex") },
245+
gas: new BN(300e12),
246+
attachedDeposit: new BN(1e12),
247+
});
248+
return { id: outcome.transaction.hash, info: outcome };
249+
}
250+
140251
getBaseUpdateFee(): Promise<{ amount: string; denom?: string }> {
141252
throw new Error("near contract doesn't implement getBaseUpdateFee method");
142253
}
@@ -145,27 +256,9 @@ export class NearPriceFeedContract extends PriceFeedContract {
145256
"near contract doesn't implement getLastExecutedGovernanceSequence method"
146257
);
147258
}
148-
149-
executeGovernanceInstruction(
150-
senderPrivateKey: PrivateKey,
151-
vaa: Buffer
152-
): Promise<TxResult> {
153-
throw new Error("Method not implemented.");
154-
}
155259
getGovernanceDataSource(): Promise<DataSource> {
156-
throw new Error("Method not implemented.");
157-
}
158-
getId(): string {
159-
return `${this.chain.getId()}_${this.address.replace(/-|\./g, "_")}`;
160-
}
161-
getType(): string {
162-
return NearPriceFeedContract.type;
163-
}
164-
toJson(): KeyValueConfig {
165-
return {
166-
chain: this.chain.getId(),
167-
address: this.address,
168-
type: NearPriceFeedContract.type,
169-
};
260+
throw new Error(
261+
"near contract doesn't implement getGovernanceDataSource method"
262+
);
170263
}
171264
}

contract_manager/src/store.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
StarknetPriceFeedContract,
3737
StarknetWormholeContract,
3838
} from "./contracts/starknet";
39-
import { NearPriceFeedContract } from "./contracts/near";
39+
import { NearPriceFeedContract, NearWormholeContract } from "./contracts/near";
4040

4141
export class Store {
4242
public chains: Record<string, Chain> = { global: new GlobalChain() };
@@ -160,6 +160,7 @@ export class Store {
160160
[TonPriceFeedContract.type]: TonPriceFeedContract,
161161
[TonWormholeContract.type]: TonWormholeContract,
162162
[NearPriceFeedContract.type]: NearPriceFeedContract,
163+
[NearWormholeContract.type]: NearWormholeContract,
163164
};
164165
this.getYamlFiles(`${this.path}/contracts/`).forEach((yamlFile) => {
165166
const parsedArray = parse(readFileSync(yamlFile, "utf-8"));
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- chain: near
2+
address: contract.wormhole_crypto.near
3+
type: NearWormholeContract
4+
- chain: near_testnet
5+
address: wormhole.wormhole.testnet
6+
type: NearWormholeContract

governance/xc_admin/packages/xc_admin_common/src/governance_payload/UpgradeContract.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class CosmosUpgradeContract extends PythGovernanceActionImpl {
3434
}
3535
}
3636

37-
// Used by Aptos, Sui and Starknet
37+
// Used by Aptos, Sui, Near, and Starknet
3838
export class UpgradeContract256Bit extends PythGovernanceActionImpl {
3939
static layout: BufferLayout.Structure<Readonly<{ hash: string }>> =
4040
BufferLayout.struct([BufferLayoutExt.hexBytes(32, "hash")]);

0 commit comments

Comments
 (0)