@wormhole-foundation/sdk-definitions 0.1.0-beta.3
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/README.md +3 -0
- package/__tests__/connectVAA.ts +21 -0
- package/__tests__/governanceVaa.ts +139 -0
- package/__tests__/relayerVaa.ts +24 -0
- package/__tests__/transferVaa.ts +28 -0
- package/package.json +20 -0
- package/src/address.ts +105 -0
- package/src/attestation.ts +42 -0
- package/src/chain.ts +105 -0
- package/src/contracts.ts +24 -0
- package/src/index.ts +25 -0
- package/src/layout-items/amount.ts +6 -0
- package/src/layout-items/chain.ts +57 -0
- package/src/layout-items/guardianSet.ts +6 -0
- package/src/layout-items/index.ts +7 -0
- package/src/layout-items/payloadId.ts +10 -0
- package/src/layout-items/sequence.ts +6 -0
- package/src/layout-items/signature.ts +27 -0
- package/src/layout-items/universalAddress.ts +14 -0
- package/src/payloads/connect.ts +52 -0
- package/src/payloads/governance.ts +219 -0
- package/src/payloads/relayer.ts +101 -0
- package/src/payloads/tokenBridge.ts +93 -0
- package/src/platform.ts +57 -0
- package/src/protocols/cctp.ts +47 -0
- package/src/protocols/core.ts +10 -0
- package/src/protocols/tokenBridge.ts +70 -0
- package/src/relayer.ts +50 -0
- package/src/rpc.ts +16 -0
- package/src/signature.ts +26 -0
- package/src/testing/README.md +4 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/mocks/api.ts +9 -0
- package/src/testing/mocks/chain.ts +18 -0
- package/src/testing/mocks/contracts.ts +57 -0
- package/src/testing/mocks/index.ts +5 -0
- package/src/testing/mocks/platform.ts +146 -0
- package/src/testing/mocks/rpc.ts +12 -0
- package/src/testing/mocks/tokenBridge.ts +68 -0
- package/src/testing/utils/address.ts +65 -0
- package/src/testing/utils/index.ts +2 -0
- package/src/testing/utils/vaa.ts +13 -0
- package/src/types.ts +73 -0
- package/src/universalAddress.ts +57 -0
- package/src/unsignedTransaction.ts +12 -0
- package/src/utils.ts +4 -0
- package/src/vaa.ts +236 -0
- package/tsconfig.cjs.json +8 -0
- package/tsconfig.esm.json +8 -0
- package/typedoc.json +4 -0
package/src/relayer.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Chain, PlatformName } from "@wormhole-foundation/sdk-base";
|
|
2
|
+
import { UniversalOrNative } from "./address";
|
|
3
|
+
|
|
4
|
+
export interface Relayer<P extends PlatformName> {
|
|
5
|
+
relaySupported(chain: Chain): boolean;
|
|
6
|
+
getRelayerFee(
|
|
7
|
+
sourceChain: Chain,
|
|
8
|
+
destChain: Chain,
|
|
9
|
+
tokenId: UniversalOrNative<P>
|
|
10
|
+
): Promise<bigint>;
|
|
11
|
+
// TODO: What should this be named?
|
|
12
|
+
// I don't think it should return an UnisgnedTransaction
|
|
13
|
+
// rather it should take some signing callbacks and
|
|
14
|
+
// a ref to track the progress
|
|
15
|
+
startTransferWithRelay(
|
|
16
|
+
token: UniversalOrNative<P> | "native",
|
|
17
|
+
amount: bigint,
|
|
18
|
+
toNativeToken: string,
|
|
19
|
+
sendingChain: Chain,
|
|
20
|
+
senderAddress: string,
|
|
21
|
+
recipientChain: Chain,
|
|
22
|
+
recipientAddress: string,
|
|
23
|
+
overrides?: any
|
|
24
|
+
): Promise<any>;
|
|
25
|
+
calculateNativeTokenAmt(
|
|
26
|
+
destChain: Chain,
|
|
27
|
+
tokenId: UniversalOrNative<P>,
|
|
28
|
+
amount: bigint,
|
|
29
|
+
walletAddress: string
|
|
30
|
+
): Promise<bigint>;
|
|
31
|
+
calculateMaxSwapAmount(
|
|
32
|
+
destChain: Chain,
|
|
33
|
+
tokenId: UniversalOrNative<P>,
|
|
34
|
+
walletAddress: string
|
|
35
|
+
): Promise<bigint>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//function parseRelayerPayload(transferPayload: Buffer): ParsedRelayerPayload {
|
|
39
|
+
// return {
|
|
40
|
+
// relayerPayloadId: transferPayload.readUint8(0),
|
|
41
|
+
// relayerFee: BigNumber.from(
|
|
42
|
+
// "0x" + transferPayload.subarray(1, 33).toString("hex")
|
|
43
|
+
// ),
|
|
44
|
+
// toNativeTokenAmount: BigNumber.from(
|
|
45
|
+
// "0x" + transferPayload.subarray(33, 65).toString("hex")
|
|
46
|
+
// ),
|
|
47
|
+
// to: "0x" + transferPayload.subarray(65, 98).toString("hex"),
|
|
48
|
+
// };
|
|
49
|
+
//}
|
|
50
|
+
//
|
package/src/rpc.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PlatformName } from "@wormhole-foundation/sdk-base";
|
|
2
|
+
|
|
3
|
+
export interface EvmRpc {
|
|
4
|
+
broadcastTransaction(stxns: string): Promise<any>;
|
|
5
|
+
getBalance(address: string): Promise<bigint>;
|
|
6
|
+
}
|
|
7
|
+
export interface SolRpc {
|
|
8
|
+
getBalance(publicKey: any, commitmentOrConfig: any): Promise<number>;
|
|
9
|
+
getParsedAccountInfo(publickKey: any): Promise<any>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type RpcConnection<P extends PlatformName> = P extends "Evm"
|
|
13
|
+
? EvmRpc
|
|
14
|
+
: P extends "Solana"
|
|
15
|
+
? SolRpc
|
|
16
|
+
: never;
|
package/src/signature.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//TODO this should get properly wrapped and get its own interface so we don't expose implementation
|
|
2
|
+
// internals and can swap out the implementation if we choose to later. Maybe also rename
|
|
3
|
+
// recovery to v then (this seems to be the convention at least in EVM land)
|
|
4
|
+
|
|
5
|
+
import { Signature as SignatureOptionalRecovery } from "@noble/secp256k1";
|
|
6
|
+
|
|
7
|
+
export class Signature extends SignatureOptionalRecovery {
|
|
8
|
+
constructor(
|
|
9
|
+
readonly r: bigint,
|
|
10
|
+
readonly s: bigint,
|
|
11
|
+
readonly recovery: number
|
|
12
|
+
) {
|
|
13
|
+
super(r, s, recovery);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
toUint8Array(): Uint8Array {
|
|
17
|
+
const buff = new Uint8Array(65);
|
|
18
|
+
buff.set(this.toCompactRawBytes());
|
|
19
|
+
buff.set([this.recovery], 64);
|
|
20
|
+
return buff;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
toBuffer(): Buffer {
|
|
24
|
+
return Buffer.from(this.toUint8Array());
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ChainName, PlatformName } from "@wormhole-foundation/sdk-base";
|
|
2
|
+
import { RpcConnection, ChainContext, Platform } from "../..";
|
|
3
|
+
|
|
4
|
+
export function chainFactory<P extends PlatformName>(
|
|
5
|
+
p: Platform<P>,
|
|
6
|
+
chain: ChainName
|
|
7
|
+
): ChainContext<P> {
|
|
8
|
+
return new MockChain<P>(p, chain);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class MockChain<P extends PlatformName> extends ChainContext<P> {
|
|
12
|
+
private rpc?: RpcConnection<P>;
|
|
13
|
+
|
|
14
|
+
getRpc(): RpcConnection<P> {
|
|
15
|
+
this.rpc = this.rpc ? this.rpc : this.platform.getRpc(this.chain);
|
|
16
|
+
return this.rpc!;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ChainName, ChainId, toChainName } from "@wormhole-foundation/sdk-base";
|
|
2
|
+
import { ChainsConfig, Contracts } from "../..";
|
|
3
|
+
|
|
4
|
+
export class MockContracts {
|
|
5
|
+
protected _contracts: Map<ChainName, Contracts>;
|
|
6
|
+
|
|
7
|
+
constructor(conf: ChainsConfig) {
|
|
8
|
+
this._contracts = new Map();
|
|
9
|
+
Object.entries(conf).forEach(([c, cfg]) => {
|
|
10
|
+
this._contracts.set(c as ChainName, cfg.contracts);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getContracts(chain: ChainName | ChainId): any | undefined {
|
|
15
|
+
const chainName = toChainName(chain);
|
|
16
|
+
return this._contracts.get(chainName);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
mustGetContracts(chain: ChainName | ChainId): any {
|
|
20
|
+
const chainName = toChainName(chain);
|
|
21
|
+
const contracts = this._contracts.get(chainName);
|
|
22
|
+
if (!contracts) throw new Error(`no Sui contracts found for ${chain}`);
|
|
23
|
+
return contracts;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getCore(chain: ChainName | ChainId) {
|
|
27
|
+
throw new Error("Method not implemented.");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
mustGetCore(chain: ChainName | ChainId) {
|
|
31
|
+
throw new Error("Method not implemented.");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
getBridge(chain: ChainName | ChainId) {
|
|
35
|
+
throw new Error("Method not implemented.");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
mustGetBridge(chain: ChainName | ChainId) {
|
|
39
|
+
throw new Error("Method not implemented.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getNftBridge(chain: ChainName | ChainId) {
|
|
43
|
+
throw new Error("Method not implemented.");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
mustGetNftBridge(chain: ChainName | ChainId) {
|
|
47
|
+
throw new Error("Method not implemented.");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getTokenBridgeRelayer(chain: ChainName | ChainId) {
|
|
51
|
+
throw new Error("Method not implemented.");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
mustGetTokenBridgeRelayer(chain: ChainName | ChainId) {
|
|
55
|
+
throw new Error("Method not implemented.");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChainName,
|
|
3
|
+
PlatformName,
|
|
4
|
+
chainToPlatform,
|
|
5
|
+
} from "@wormhole-foundation/sdk-base";
|
|
6
|
+
import {
|
|
7
|
+
ChainContext,
|
|
8
|
+
Platform,
|
|
9
|
+
TxHash,
|
|
10
|
+
RpcConnection,
|
|
11
|
+
TokenId,
|
|
12
|
+
AutomaticTokenBridge,
|
|
13
|
+
TokenBridge,
|
|
14
|
+
UniversalAddress,
|
|
15
|
+
WormholeMessageId,
|
|
16
|
+
CircleBridge,
|
|
17
|
+
AutomaticCircleBridge,
|
|
18
|
+
ChainsConfig,
|
|
19
|
+
PlatformCtr,
|
|
20
|
+
toNative,
|
|
21
|
+
nativeIsRegistered,
|
|
22
|
+
NativeAddress,
|
|
23
|
+
} from "../..";
|
|
24
|
+
import { MockRpc } from "./rpc";
|
|
25
|
+
import { MockChain } from "./chain";
|
|
26
|
+
import { MockTokenBridge } from "./tokenBridge";
|
|
27
|
+
import { WormholeCore } from "../../protocols/core";
|
|
28
|
+
|
|
29
|
+
export function mockPlatformFactory(
|
|
30
|
+
p: PlatformName
|
|
31
|
+
): PlatformCtr<PlatformName> {
|
|
32
|
+
class ConcreteMockPlatform extends MockPlatform<typeof p> {
|
|
33
|
+
static _platform: typeof p = p;
|
|
34
|
+
readonly platform = ConcreteMockPlatform._platform;
|
|
35
|
+
}
|
|
36
|
+
return ConcreteMockPlatform;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Note: don't use this directly, instead create a ConcreteMockPlatform with the
|
|
40
|
+
// mockPlatformFactory
|
|
41
|
+
export class MockPlatform<P extends PlatformName> implements Platform<P> {
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
readonly platform: P;
|
|
44
|
+
|
|
45
|
+
conf: ChainsConfig;
|
|
46
|
+
|
|
47
|
+
constructor(conf: ChainsConfig) {
|
|
48
|
+
this.conf = conf;
|
|
49
|
+
}
|
|
50
|
+
getDecimals(
|
|
51
|
+
chain: ChainName,
|
|
52
|
+
rpc: RpcConnection<P>,
|
|
53
|
+
token: TokenId | "native"
|
|
54
|
+
): Promise<bigint> {
|
|
55
|
+
throw new Error("Method not implemented.");
|
|
56
|
+
}
|
|
57
|
+
getBalance(
|
|
58
|
+
chain: ChainName,
|
|
59
|
+
rpc: RpcConnection<P>,
|
|
60
|
+
walletAddr: string,
|
|
61
|
+
token: TokenId | "native"
|
|
62
|
+
): Promise<bigint | null> {
|
|
63
|
+
throw new Error("Method not implemented.");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
getChain(chain: ChainName): ChainContext<P> {
|
|
67
|
+
return new MockChain<P>(this, chain);
|
|
68
|
+
}
|
|
69
|
+
getRpc(chain: ChainName): RpcConnection<P> {
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
return new MockRpc(chain);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async getWrappedAsset(
|
|
75
|
+
chain: ChainName,
|
|
76
|
+
rpc: RpcConnection<P>,
|
|
77
|
+
token: TokenId
|
|
78
|
+
): Promise<TokenId | null> {
|
|
79
|
+
throw new Error("Method not implemented.");
|
|
80
|
+
}
|
|
81
|
+
async getTokenDecimals(
|
|
82
|
+
rpc: RpcConnection<P>,
|
|
83
|
+
token: TokenId
|
|
84
|
+
): Promise<bigint> {
|
|
85
|
+
return 8n;
|
|
86
|
+
}
|
|
87
|
+
async getNativeBalance(
|
|
88
|
+
rpc: RpcConnection<P>,
|
|
89
|
+
walletAddr: string
|
|
90
|
+
): Promise<bigint> {
|
|
91
|
+
return 0n;
|
|
92
|
+
}
|
|
93
|
+
async getTokenBalance(
|
|
94
|
+
chain: ChainName,
|
|
95
|
+
rpc: RpcConnection<P>,
|
|
96
|
+
walletAddr: string,
|
|
97
|
+
token: TokenId
|
|
98
|
+
): Promise<bigint | null> {
|
|
99
|
+
return 10n;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async parseTransaction(
|
|
103
|
+
chain: ChainName,
|
|
104
|
+
rpc: RpcConnection<P>,
|
|
105
|
+
txid: TxHash
|
|
106
|
+
): Promise<WormholeMessageId[]> {
|
|
107
|
+
throw new Error("Method not implemented");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
parseAddress(chain: ChainName, address: string): NativeAddress<P> {
|
|
111
|
+
if (!nativeIsRegistered(chain)) throw new Error("Chain not registered");
|
|
112
|
+
//@ts-ignore
|
|
113
|
+
return toNative(chain, address).toUniversalAddress();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async sendWait(rpc: RpcConnection<P>, stxns: any[]): Promise<TxHash[]> {
|
|
117
|
+
throw new Error("Method not implemented.");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async getWormholeCore(rpc: RpcConnection<P>): Promise<WormholeCore<P>> {
|
|
121
|
+
throw new Error("Method not implemented.");
|
|
122
|
+
}
|
|
123
|
+
async getTokenBridge(rpc: RpcConnection<P>): Promise<TokenBridge<P>> {
|
|
124
|
+
// @ts-ignore
|
|
125
|
+
return new MockTokenBridge<P>(rpc);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async getAutomaticTokenBridge(
|
|
129
|
+
rpc: RpcConnection<P>
|
|
130
|
+
): Promise<AutomaticTokenBridge<P>> {
|
|
131
|
+
throw new Error("Method not implemented.");
|
|
132
|
+
}
|
|
133
|
+
async getCircleBridge(rpc: RpcConnection<P>): Promise<CircleBridge<P>> {
|
|
134
|
+
throw new Error("Method not implemented.");
|
|
135
|
+
}
|
|
136
|
+
async getCircleRelayer(
|
|
137
|
+
rpc: RpcConnection<P>
|
|
138
|
+
): Promise<AutomaticCircleBridge<P>> {
|
|
139
|
+
throw new Error("Method Not implemented.");
|
|
140
|
+
}
|
|
141
|
+
async getAutomaticCircleBridge(
|
|
142
|
+
rpc: RpcConnection<P>
|
|
143
|
+
): Promise<AutomaticCircleBridge<P>> {
|
|
144
|
+
throw new Error("Method not implemented.");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChainName } from '@wormhole-foundation/sdk-base';
|
|
2
|
+
|
|
3
|
+
export class MockRpc {
|
|
4
|
+
constructor(chain: ChainName) {}
|
|
5
|
+
|
|
6
|
+
getBalance(address: string): Promise<bigint> {
|
|
7
|
+
throw new Error('Method not implemented.');
|
|
8
|
+
}
|
|
9
|
+
broadcastTransaction(stxns: any): any {
|
|
10
|
+
throw new Error('Not implemented');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { PlatformName } from "@wormhole-foundation/sdk-base";
|
|
2
|
+
import {
|
|
3
|
+
ChainAddress,
|
|
4
|
+
NativeAddress,
|
|
5
|
+
RpcConnection,
|
|
6
|
+
TokenBridge,
|
|
7
|
+
TokenId,
|
|
8
|
+
UniversalOrNative,
|
|
9
|
+
UnsignedTransaction,
|
|
10
|
+
VAA,
|
|
11
|
+
} from "../..";
|
|
12
|
+
|
|
13
|
+
//export function mockTokenBridgeFactory(
|
|
14
|
+
// p: PlatformName,
|
|
15
|
+
//): TokenBridge<PlatformName> {
|
|
16
|
+
// return new MockTokenBridge(p);
|
|
17
|
+
//}
|
|
18
|
+
|
|
19
|
+
export class MockTokenBridge<P extends PlatformName> implements TokenBridge<P> {
|
|
20
|
+
constructor(readonly rpc: RpcConnection<P>) {}
|
|
21
|
+
|
|
22
|
+
isWrappedAsset(token: UniversalOrNative<P>): Promise<boolean> {
|
|
23
|
+
throw new Error("Method not implemented.");
|
|
24
|
+
}
|
|
25
|
+
getOriginalAsset(token: UniversalOrNative<P>): Promise<ChainAddress> {
|
|
26
|
+
throw new Error("Method not implemented.");
|
|
27
|
+
}
|
|
28
|
+
hasWrappedAsset(original: ChainAddress): Promise<boolean> {
|
|
29
|
+
throw new Error("Method not implemented.");
|
|
30
|
+
}
|
|
31
|
+
async getWrappedAsset(original: ChainAddress): Promise<NativeAddress<P>> {
|
|
32
|
+
throw new Error("Method not implemented.");
|
|
33
|
+
}
|
|
34
|
+
isTransferCompleted(
|
|
35
|
+
vaa: VAA<"Transfer"> | VAA<"TransferWithPayload">
|
|
36
|
+
): Promise<boolean> {
|
|
37
|
+
throw new Error("Method not implemented.");
|
|
38
|
+
}
|
|
39
|
+
createAttestation(
|
|
40
|
+
address: UniversalOrNative<P>
|
|
41
|
+
): AsyncGenerator<UnsignedTransaction> {
|
|
42
|
+
throw new Error("Method not implemented.");
|
|
43
|
+
}
|
|
44
|
+
submitAttestation(
|
|
45
|
+
vaa: VAA<"AttestMeta">
|
|
46
|
+
): AsyncGenerator<UnsignedTransaction> {
|
|
47
|
+
throw new Error("Method not implemented.");
|
|
48
|
+
}
|
|
49
|
+
transfer(
|
|
50
|
+
sender: UniversalOrNative<P>,
|
|
51
|
+
recipient: ChainAddress,
|
|
52
|
+
token: "native" | UniversalOrNative<P>,
|
|
53
|
+
amount: bigint,
|
|
54
|
+
payload?: Uint8Array | undefined
|
|
55
|
+
): AsyncGenerator<UnsignedTransaction> {
|
|
56
|
+
throw new Error("Method not implemented.");
|
|
57
|
+
}
|
|
58
|
+
redeem(
|
|
59
|
+
sender: UniversalOrNative<P>,
|
|
60
|
+
vaa: VAA<"Transfer"> | VAA<"TransferWithPayload">,
|
|
61
|
+
unwrapNative?: boolean | undefined
|
|
62
|
+
): AsyncGenerator<UnsignedTransaction> {
|
|
63
|
+
throw new Error("Method not implemented.");
|
|
64
|
+
}
|
|
65
|
+
getWrappedNative(): Promise<NativeAddress<P>> {
|
|
66
|
+
throw new Error("Method not implemented.");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import {
|
|
3
|
+
ChainName,
|
|
4
|
+
PlatformName,
|
|
5
|
+
chainToPlatform,
|
|
6
|
+
isPlatform,
|
|
7
|
+
platformToChains,
|
|
8
|
+
} from "@wormhole-foundation/sdk-base";
|
|
9
|
+
import {
|
|
10
|
+
ChainAddress,
|
|
11
|
+
NativeAddress,
|
|
12
|
+
UniversalAddress,
|
|
13
|
+
toNative,
|
|
14
|
+
} from "../../";
|
|
15
|
+
|
|
16
|
+
// return a random buffer of length n
|
|
17
|
+
function randomBuffer(n: number): Buffer {
|
|
18
|
+
const buff = new Uint8Array(n);
|
|
19
|
+
crypto.getRandomValues(buff);
|
|
20
|
+
return Buffer.from(buff);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// get a random 20 byte address
|
|
24
|
+
function fake20ByteAddress(): string {
|
|
25
|
+
const buff = randomBuffer(20);
|
|
26
|
+
return buff.toString("hex");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// get a random 32 byte address
|
|
30
|
+
function fake32ByteAddress(): string {
|
|
31
|
+
const buff = randomBuffer(32);
|
|
32
|
+
return buff.toString("hex");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// make a random native address for a given chain
|
|
36
|
+
export function makeNativeAddressHexString(chain: ChainName): string {
|
|
37
|
+
switch (chainToPlatform(chain)) {
|
|
38
|
+
case "Evm":
|
|
39
|
+
return fake20ByteAddress();
|
|
40
|
+
default:
|
|
41
|
+
return fake32ByteAddress();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// make a random ChainAddress for a given chain
|
|
46
|
+
export function makeChainAddress(chain: ChainName): ChainAddress {
|
|
47
|
+
const nativeAddress = makeNativeAddressHexString(chain);
|
|
48
|
+
const address = new UniversalAddress("0x" + nativeAddress.padStart(64, "0"));
|
|
49
|
+
return { chain, address };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// make a random NativeAddress for a given chain
|
|
53
|
+
export function makeNativeAddress<T extends ChainName | PlatformName>(
|
|
54
|
+
chain: T
|
|
55
|
+
): NativeAddress<T> {
|
|
56
|
+
let cn: ChainName;
|
|
57
|
+
if (isPlatform(chain)) {
|
|
58
|
+
// just grab the first one
|
|
59
|
+
cn = platformToChains(chain)[0];
|
|
60
|
+
} else {
|
|
61
|
+
cn = chain;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return toNative(cn, makeNativeAddressHexString(cn)) as NativeAddress<T>;
|
|
65
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PayloadLiteralToPayloadType } from "../../vaa";
|
|
2
|
+
|
|
3
|
+
export function makeVAA(payload: any) {
|
|
4
|
+
return {
|
|
5
|
+
version: 1,
|
|
6
|
+
guardianSetIndex: 0,
|
|
7
|
+
timestamp: 0,
|
|
8
|
+
nonce: 0,
|
|
9
|
+
payload: payload,
|
|
10
|
+
guardianSignature: new Uint8Array(65),
|
|
11
|
+
hash: new Uint8Array(32),
|
|
12
|
+
} as const;
|
|
13
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChainName,
|
|
3
|
+
ExplorerSettings,
|
|
4
|
+
PlatformName,
|
|
5
|
+
isChain,
|
|
6
|
+
} from "@wormhole-foundation/sdk-base";
|
|
7
|
+
import { ChainAddress, toNative } from "./address";
|
|
8
|
+
import { Contracts } from "./contracts";
|
|
9
|
+
import { UnsignedTransaction } from "./unsignedTransaction";
|
|
10
|
+
|
|
11
|
+
export type TxHash = string;
|
|
12
|
+
export type SequenceId = bigint;
|
|
13
|
+
|
|
14
|
+
export type SignedTx = any;
|
|
15
|
+
|
|
16
|
+
export type TokenId = ChainAddress;
|
|
17
|
+
export function isTokenId(thing: TokenId | any): thing is TokenId {
|
|
18
|
+
return (
|
|
19
|
+
typeof (<TokenId>thing).address !== undefined &&
|
|
20
|
+
isChain((<TokenId>thing).chain)
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface Signer {
|
|
25
|
+
chain(): ChainName;
|
|
26
|
+
address(): string;
|
|
27
|
+
sign(tx: UnsignedTransaction[]): Promise<SignedTx[]>;
|
|
28
|
+
}
|
|
29
|
+
export function isSigner(thing: Signer | any): thing is Signer {
|
|
30
|
+
return (
|
|
31
|
+
typeof (<Signer>thing).chain === "function" &&
|
|
32
|
+
typeof (<Signer>thing).address == "function" &&
|
|
33
|
+
typeof (<Signer>thing).sign === "function"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function nativeChainAddress(s: Signer | TokenId): TokenId {
|
|
38
|
+
if (isSigner(s))
|
|
39
|
+
return {
|
|
40
|
+
chain: s.chain(),
|
|
41
|
+
address: toNative(s.chain(), s.address()),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
chain: s.chain,
|
|
46
|
+
address: s.address.toNative(s.chain),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Fully qualifier Transaction ID
|
|
51
|
+
export type TransactionId = { chain: ChainName; txid: TxHash };
|
|
52
|
+
export function isTransactionIdentifier(
|
|
53
|
+
thing: TransactionId | any
|
|
54
|
+
): thing is TransactionId {
|
|
55
|
+
return (
|
|
56
|
+
(<TransactionId>thing).chain !== undefined &&
|
|
57
|
+
(<TransactionId>thing).txid !== undefined
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type ChainConfig = {
|
|
62
|
+
key: ChainName;
|
|
63
|
+
platform: PlatformName;
|
|
64
|
+
contracts: Contracts;
|
|
65
|
+
finalityThreshold: number;
|
|
66
|
+
nativeTokenDecimals: number;
|
|
67
|
+
explorer: ExplorerSettings;
|
|
68
|
+
rpc: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type ChainsConfig = {
|
|
72
|
+
[K in ChainName]?: ChainConfig;
|
|
73
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hexByteStringToUint8Array,
|
|
3
|
+
uint8ArrayToHexByteString,
|
|
4
|
+
isHexByteString,
|
|
5
|
+
} from "@wormhole-foundation/sdk-base";
|
|
6
|
+
|
|
7
|
+
import { Address, NativeAddress, toNative } from "./address";
|
|
8
|
+
|
|
9
|
+
export class UniversalAddress implements Address {
|
|
10
|
+
static readonly byteSize = 32;
|
|
11
|
+
|
|
12
|
+
private readonly address: Uint8Array;
|
|
13
|
+
|
|
14
|
+
constructor(address: string | Uint8Array) {
|
|
15
|
+
if (typeof address === "string") {
|
|
16
|
+
if (!UniversalAddress.isValidAddress(address))
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Invalid Wormhole address, expected ${UniversalAddress.byteSize}-byte ` +
|
|
19
|
+
`hex string but got ${address}`
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
this.address = hexByteStringToUint8Array(address);
|
|
23
|
+
} else {
|
|
24
|
+
this.address = address;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
toNative<T extends Parameters<typeof toNative>[0]>(
|
|
29
|
+
platform: T
|
|
30
|
+
): NativeAddress<T> {
|
|
31
|
+
return toNative(platform, this);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
unwrap(): Uint8Array {
|
|
35
|
+
return this.address;
|
|
36
|
+
}
|
|
37
|
+
toString() {
|
|
38
|
+
return uint8ArrayToHexByteString(this.address);
|
|
39
|
+
}
|
|
40
|
+
toUint8Array() {
|
|
41
|
+
return this.address;
|
|
42
|
+
}
|
|
43
|
+
toUniversalAddress() {
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
equals(other: UniversalAddress): boolean {
|
|
48
|
+
if (other instanceof UniversalAddress) {
|
|
49
|
+
return other.toString() === this.toString();
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static isValidAddress(address: string) {
|
|
55
|
+
return isHexByteString(address, UniversalAddress.byteSize);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChainName, Network } from "@wormhole-foundation/sdk-base";
|
|
2
|
+
|
|
3
|
+
export interface UnsignedTransaction {
|
|
4
|
+
readonly transaction: any;
|
|
5
|
+
readonly network: Network;
|
|
6
|
+
readonly chain: ChainName;
|
|
7
|
+
readonly description: string;
|
|
8
|
+
// parallelizable describes whether or not the transaction can be
|
|
9
|
+
// executed in parallel with others.
|
|
10
|
+
// If order matters, this will be false to ensure ordered execution
|
|
11
|
+
readonly parallelizable: boolean;
|
|
12
|
+
}
|
package/src/utils.ts
ADDED