Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sdk: Added resume transfer methods to routes #487

Merged
merged 5 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions evm/ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@
"test": "jest --config ./jest.config.ts"
},
"dependencies": {
"@wormhole-foundation/sdk-base": "^0.8",
"@wormhole-foundation/sdk-definitions": "^0.8",
"@wormhole-foundation/sdk-base": "^0.9.1",
"@wormhole-foundation/sdk-definitions": "^0.9.1",
"@wormhole-foundation/sdk-definitions-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-evm": "^0.8",
"@wormhole-foundation/sdk-evm-core": "^0.8",
"@wormhole-foundation/sdk-evm": "^0.9.1",
"@wormhole-foundation/sdk-evm-core": "^0.9.1",
"ethers": "^6.5.1"
},
"peerDependencies": {
"@wormhole-foundation/sdk-definitions-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-base": "^0.8",
"@wormhole-foundation/sdk-definitions": "^0.8",
"@wormhole-foundation/sdk-evm": "^0.8",
"@wormhole-foundation/sdk-evm-core": "^0.8"
"@wormhole-foundation/sdk-base": "^0.9.1",
"@wormhole-foundation/sdk-definitions": "^0.9.1",
"@wormhole-foundation/sdk-evm": "^0.9.1",
"@wormhole-foundation/sdk-evm-core": "^0.9.1"
},
"devDependencies": {
"@typechain/ethers-v6": "^0.5.1",
Expand Down
750 changes: 221 additions & 529 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"version": "tsx setSdkVersion.ts"
},
"devDependencies": {
"@wormhole-foundation/sdk": "^0.8",
"@wormhole-foundation/sdk": "^0.9.1",
"@solana/spl-token": "0.3.9",
"@solana/web3.js": "1.91.7",
"@types/jest": "^29.5.12",
Expand Down
8 changes: 4 additions & 4 deletions sdk/definitions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@
"test": "jest --config ./jest.config.ts"
},
"dependencies": {
"@wormhole-foundation/sdk-base": "^0.8",
"@wormhole-foundation/sdk-definitions": "^0.8"
"@wormhole-foundation/sdk-base": "^0.9.1",
"@wormhole-foundation/sdk-definitions": "^0.9.1"
},
"peerDependencies": {
"@wormhole-foundation/sdk-base": "^0.8",
"@wormhole-foundation/sdk-definitions": "^0.8"
"@wormhole-foundation/sdk-base": "^0.9.1",
"@wormhole-foundation/sdk-definitions": "^0.9.1"
},
"type": "module"
}
2 changes: 1 addition & 1 deletion sdk/examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"tsx": "^4.7.2"
},
"dependencies": {
"@wormhole-foundation/sdk": "^0.8",
"@wormhole-foundation/sdk": "^0.9.1",
"@wormhole-foundation/sdk-definitions-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-evm-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-solana-ntt": "0.1.0-beta.0",
Expand Down
2 changes: 2 additions & 0 deletions sdk/route/__tests__/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ describe("Manual Route Tests", function () {
"params",
"sourceToken",
"destinationToken",
"eta",
]);
});
});
Expand Down Expand Up @@ -249,6 +250,7 @@ describe("Automatic Route Tests", function () {
"destinationToken",
"relayFee",
"destinationNativeGas",
"eta",
]);
});
});
6 changes: 3 additions & 3 deletions sdk/route/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@
"@wormhole-foundation/sdk-definitions-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-solana-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-evm-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-connect": "^0.8"
"@wormhole-foundation/sdk-connect": "^0.9.1"
},
"peerDependencies": {
"@wormhole-foundation/sdk-connect": "^0.8",
"@wormhole-foundation/sdk-connect": "^0.9.1",
"@wormhole-foundation/sdk-definitions-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-solana-ntt": "0.1.0-beta.0",
"@wormhole-foundation/sdk-evm-ntt": "0.1.0-beta.0"
Expand All @@ -69,4 +69,4 @@
}
}
}
}
}
85 changes: 85 additions & 0 deletions sdk/route/src/automatic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import {
RedeemedTransferReceipt,
Signer,
TokenId,
TransactionId,
TransferState,
Wormhole,
WormholeMessageId,
amount,
canonicalAddress,
chainToPlatform,
finality,
isAttested,
isDestinationQueued,
isRedeemed,
Expand Down Expand Up @@ -179,6 +182,7 @@ export class NttAutomaticRoute<N extends Network>
params.normalizedParams.options.gasDropoff ?? 0n,
toChain.config.nativeTokenDecimals
),
eta: finality.estimateFinalityTime(request.fromChain.chain),
};
const dstNtt = await toChain.getProtocol("Ntt", {
ntt: params.normalizedParams.destinationContracts,
Expand Down Expand Up @@ -235,6 +239,87 @@ export class NttAutomaticRoute<N extends Network>
};
}

async resume(tx: TransactionId): Promise<R> {
const vaa = await this.wh.getVaa(
tx.txid,
"Ntt:WormholeTransferStandardRelayer"
);
if (!vaa) throw new Error("No VAA found for transaction: " + tx.txid);

const msgId: WormholeMessageId = {
chain: vaa.emitterChain,
emitter: vaa.emitterAddress,
sequence: vaa.sequence,
};

const { payload } = vaa.payload;
const { recipientChain, trimmedAmount } =
payload["nttManagerPayload"].payload;

const token = canonicalAddress({
chain: vaa.emitterChain,
address: payload["nttManagerPayload"].payload.sourceToken,
});
const manager = canonicalAddress({
chain: vaa.emitterChain,
address: payload["sourceNttManager"],
});
const whTransceiver =
vaa.emitterChain === "Solana"
? manager
: canonicalAddress({
chain: vaa.emitterChain,
address: vaa.emitterAddress,
});

const dstInfo = NttRoute.resolveDestinationNttContracts(
this.staticConfig,
{
chain: vaa.emitterChain,
address: payload["sourceNttManager"],
},
recipientChain
);

const amt = amount.fromBaseUnits(
trimmedAmount.amount,
trimmedAmount.decimals
);

return {
from: vaa.emitterChain,
to: recipientChain,
state: TransferState.Attested,
originTxs: [tx],
attestation: {
id: msgId,
attestation: vaa,
},
params: {
kev1n-peters marked this conversation as resolved.
Show resolved Hide resolved
amount: amount.display(amt),
options: { automatic: true },
normalizedParams: {
amount: amt,
options: { queue: false, automatic: true },
sourceContracts: {
token,
manager,
transceiver: {
wormhole: whTransceiver,
},
},
destinationContracts: {
token: dstInfo.token,
manager: dstInfo.manager,
transceiver: {
wormhole: dstInfo.transceiver.wormhole,
},
},
},
},
};
}

// Even though this is an automatic route, the transfer may need to be
// manually finalized if it was queued
async finalize(signer: Signer, receipt: R): Promise<R> {
Expand Down
81 changes: 81 additions & 0 deletions sdk/route/src/manual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ import {
RedeemedTransferReceipt,
Signer,
TokenId,
TransactionId,
TransferState,
Wormhole,
WormholeMessageId,
amount,
canonicalAddress,
isAttested,
isDestinationQueued,
isRedeemed,
isSourceFinalized,
isSourceInitiated,
routes,
signSendWait,
finality,
} from "@wormhole-foundation/sdk-connect";
import "@wormhole-foundation/sdk-definitions-ntt";
import { NttRoute } from "./types.js";
Expand Down Expand Up @@ -145,6 +148,7 @@ export class NttManualRoute<N extends Network>
token: request.destination.id,
amount: amount.parse(params.amount, request.destination.decimals),
},
eta: finality.estimateFinalityTime(request.fromChain.chain),
kev1n-peters marked this conversation as resolved.
Show resolved Hide resolved
};
const { fromChain, toChain } = request;
const dstNtt = await toChain.getProtocol("Ntt", {
Expand Down Expand Up @@ -224,6 +228,83 @@ export class NttManualRoute<N extends Network>
};
}

async resume(tx: TransactionId): Promise<R> {
const vaa = await this.wh.getVaa(tx.txid, "Ntt:WormholeTransfer");
if (!vaa) throw new Error("No VAA found for transaction: " + tx.txid);

const msgId: WormholeMessageId = {
chain: vaa.emitterChain,
emitter: vaa.emitterAddress,
sequence: vaa.sequence,
};

const { recipientChain, trimmedAmount } =
vaa.payload["nttManagerPayload"].payload;

const token = canonicalAddress({
chain: vaa.emitterChain,
address: vaa.payload["nttManagerPayload"].payload.sourceToken,
});
const manager = canonicalAddress({
chain: vaa.emitterChain,
address: vaa.payload["sourceNttManager"],
});
const whTransceiver =
vaa.emitterChain === "Solana"
? manager
: canonicalAddress({
chain: vaa.emitterChain,
address: vaa.emitterAddress,
});

const dstInfo = NttRoute.resolveDestinationNttContracts(
this.staticConfig,
{
chain: vaa.emitterChain,
address: vaa.payload["sourceNttManager"],
},
recipientChain
);

const amt = amount.fromBaseUnits(
trimmedAmount.amount,
trimmedAmount.decimals
);

return {
from: vaa.emitterChain,
to: recipientChain,
state: TransferState.Attested,
originTxs: [tx],
attestation: {
id: msgId,
attestation: vaa,
},
params: {
amount: amount.display(amt),
options: { automatic: false },
normalizedParams: {
amount: amt,
options: { queue: false },
sourceContracts: {
token,
manager,
transceiver: {
wormhole: whTransceiver,
},
},
destinationContracts: {
token: dstInfo.token,
manager: dstInfo.manager,
transceiver: {
wormhole: dstInfo.transceiver.wormhole,
},
},
},
},
};
}

async finalize(signer: Signer, receipt: R): Promise<R> {
if (!isDestinationQueued(receipt)) {
throw new Error(
Expand Down
35 changes: 35 additions & 0 deletions sdk/route/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Chain,
ChainAddress,
ChainContext,
Network,
TokenId,
Expand Down Expand Up @@ -168,6 +169,40 @@ export namespace NttRoute {
throw new Error("Cannot find Ntt contracts in config for: " + address);
}

export function resolveDestinationNttContracts<C extends Chain>(
config: Config,
srcManager: ChainAddress<C>,
dstChain: Chain
): Ntt.Contracts {
const cfg = Object.values(config.tokens);
const address = canonicalAddress(srcManager);
for (const tokens of cfg) {
const found = tokens.find(
(tc) =>
tc.manager.toLowerCase() === address.toLowerCase() &&
tc.chain === srcManager.chain
);
if (found) {
const remote = tokens.find((tc) => tc.chain === dstChain);
if (!remote) {
throw new Error(
`Cannot find destination Ntt contracts in config for: ${address}`
);
}
return {
token: remote.token,
manager: remote.manager,
transceiver: {
wormhole: remote.transceiver.find((v) => v.type === "wormhole")!
.address,
},
quoter: remote.quoter,
};
}
}
throw new Error("Cannot find Ntt contracts in config for: " + address);
}

// returns true if the amount is greater than 95% of the capacity
// useful for warning about the possibility of a transfer being queued
export function isCapacityThresholdExceeded(
Expand Down
16 changes: 8 additions & 8 deletions solana/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@
"@solana/spl-token": "0.4.0",
"@solana/web3.js": "1.91.7",
"bn.js": "5.2.1",
"@wormhole-foundation/sdk-base": "^0.8",
"@wormhole-foundation/sdk-definitions": "^0.8",
"@wormhole-foundation/sdk-solana": "^0.8",
"@wormhole-foundation/sdk-solana-core": "^0.8"
"@wormhole-foundation/sdk-base": "^0.9.1",
"@wormhole-foundation/sdk-definitions": "^0.9.1",
"@wormhole-foundation/sdk-solana": "^0.9.1",
"@wormhole-foundation/sdk-solana-core": "^0.9.1"
},
"peerDependencies": {
"@wormhole-foundation/sdk-base": "^0.8",
"@wormhole-foundation/sdk-definitions": "^0.8",
"@wormhole-foundation/sdk-solana": "^0.8",
"@wormhole-foundation/sdk-solana-core": "^0.8",
"@wormhole-foundation/sdk-base": "^0.9.1",
"@wormhole-foundation/sdk-definitions": "^0.9.1",
"@wormhole-foundation/sdk-solana": "^0.9.1",
"@wormhole-foundation/sdk-solana-core": "^0.9.1",
"@wormhole-foundation/sdk-definitions-ntt": "0.1.0-beta.0"
},
"type": "module",
Expand Down
Loading