@across-protocol/sdk 4.3.33 → 4.3.34-alpha.1
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/cjs/arch/svm/SpokeUtils.d.ts +21 -10
- package/dist/cjs/arch/svm/SpokeUtils.js +134 -27
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/svm/encoders.d.ts +19 -0
- package/dist/cjs/arch/svm/encoders.js +52 -0
- package/dist/cjs/arch/svm/encoders.js.map +1 -0
- package/dist/cjs/arch/svm/index.d.ts +1 -0
- package/dist/cjs/arch/svm/index.js +1 -0
- package/dist/cjs/arch/svm/index.js.map +1 -1
- package/dist/cjs/arch/svm/utils.d.ts +2 -0
- package/dist/cjs/arch/svm/utils.js +18 -1
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/esm/arch/svm/SpokeUtils.d.ts +38 -10
- package/dist/esm/arch/svm/SpokeUtils.js +160 -28
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/encoders.d.ts +19 -0
- package/dist/esm/arch/svm/encoders.js +43 -0
- package/dist/esm/arch/svm/encoders.js.map +1 -0
- package/dist/esm/arch/svm/index.d.ts +1 -0
- package/dist/esm/arch/svm/index.js +1 -0
- package/dist/esm/arch/svm/index.js.map +1 -1
- package/dist/esm/arch/svm/utils.d.ts +8 -0
- package/dist/esm/arch/svm/utils.js +22 -0
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/types/arch/svm/SpokeUtils.d.ts +38 -10
- package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
- package/dist/types/arch/svm/encoders.d.ts +20 -0
- package/dist/types/arch/svm/encoders.d.ts.map +1 -0
- package/dist/types/arch/svm/index.d.ts +1 -0
- package/dist/types/arch/svm/index.d.ts.map +1 -1
- package/dist/types/arch/svm/utils.d.ts +8 -0
- package/dist/types/arch/svm/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/arch/svm/SpokeUtils.ts +193 -22
- package/src/arch/svm/encoders.ts +86 -0
- package/src/arch/svm/index.ts +1 -0
- package/src/arch/svm/utils.ts +23 -0
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
Address,
|
|
18
18
|
FetchAccountConfig,
|
|
19
19
|
IAccountMeta,
|
|
20
|
+
IInstruction,
|
|
20
21
|
KeyPairSigner,
|
|
21
22
|
ReadonlyUint8Array,
|
|
22
23
|
appendTransactionMessageInstruction,
|
|
@@ -32,9 +33,11 @@ import {
|
|
|
32
33
|
signTransactionMessageWithSigners,
|
|
33
34
|
some,
|
|
34
35
|
type TransactionSigner,
|
|
36
|
+
type WritableAccount,
|
|
37
|
+
type ReadonlyAccount,
|
|
35
38
|
} from "@solana/kit";
|
|
36
39
|
import assert from "assert";
|
|
37
|
-
import { arrayify
|
|
40
|
+
import { arrayify } from "ethers/lib/utils";
|
|
38
41
|
import { Logger } from "winston";
|
|
39
42
|
import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../../constants";
|
|
40
43
|
import { DepositWithBlock, FillStatus, FillWithBlock, RelayData, RelayExecutionEventInfo } from "../../interfaces";
|
|
@@ -66,6 +69,11 @@ import {
|
|
|
66
69
|
toAddress,
|
|
67
70
|
unwrapEventData,
|
|
68
71
|
getRootBundlePda,
|
|
72
|
+
getAcrossPlusMessageDecoder,
|
|
73
|
+
getAccountMeta,
|
|
74
|
+
toSvmRelayData,
|
|
75
|
+
getInstructionParamsPda,
|
|
76
|
+
type AcrossPlusMessage,
|
|
69
77
|
} from "./";
|
|
70
78
|
import { SvmCpiEventsClient } from "./eventsClient";
|
|
71
79
|
import { SVM_BLOCK_NOT_AVAILABLE, SVM_SLOT_SKIPPED, isSolanaError } from "./provider";
|
|
@@ -601,6 +609,7 @@ export async function getFillRelayTx(
|
|
|
601
609
|
getEventAuthority(program),
|
|
602
610
|
]);
|
|
603
611
|
|
|
612
|
+
const message = new Uint8Array(Buffer.from(relayData.message.slice(2), "hex"));
|
|
604
613
|
const svmRelayData: SvmSpokeClient.FillRelayInput["relayData"] = {
|
|
605
614
|
depositor: toAddress(depositor),
|
|
606
615
|
recipient: toAddress(recipient),
|
|
@@ -613,9 +622,24 @@ export async function getFillRelayTx(
|
|
|
613
622
|
depositId: new Uint8Array(intToU8Array32(relayData.depositId.toNumber())),
|
|
614
623
|
fillDeadline: relayData.fillDeadline,
|
|
615
624
|
exclusivityDeadline: relayData.exclusivityDeadline,
|
|
616
|
-
message
|
|
625
|
+
message,
|
|
617
626
|
};
|
|
618
627
|
|
|
628
|
+
// Add remaining accounts if the relayData has a non-empty message.
|
|
629
|
+
// @dev ! since in the context of creating a `fillRelayTx`, `relayData` must be defined.
|
|
630
|
+
const remainingAccounts: (WritableAccount | ReadonlyAccount)[] = [];
|
|
631
|
+
if (relayData.message !== "0x") {
|
|
632
|
+
const acrossPlusMessage = deserializeMessage(relayData.message);
|
|
633
|
+
// The first `remainingAccount` _must_ be the handler address.
|
|
634
|
+
// https://github.com/across-protocol/contracts/blob/3310f8dc716407a5f97ef5fd2eae63df83251f2f/programs/svm-spoke/src/utils/message_utils.rs#L36.
|
|
635
|
+
remainingAccounts.push(getAccountMeta(acrossPlusMessage.handler, true));
|
|
636
|
+
remainingAccounts.push(
|
|
637
|
+
...acrossPlusMessage.accounts.map((account, idx) =>
|
|
638
|
+
getAccountMeta(account, idx < acrossPlusMessage.accounts.length - acrossPlusMessage.read_only_len)
|
|
639
|
+
)
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
|
|
619
643
|
const fillInput: SvmSpokeClient.FillRelayInput = {
|
|
620
644
|
signer: signer,
|
|
621
645
|
state,
|
|
@@ -636,7 +660,105 @@ export async function getFillRelayTx(
|
|
|
636
660
|
};
|
|
637
661
|
// Pass createRecipientAtaIfNeeded =true to the createFillInstruction function to create the recipient token account
|
|
638
662
|
// if it doesn't exist.
|
|
639
|
-
return createFillInstruction(
|
|
663
|
+
return createFillInstruction(
|
|
664
|
+
signer,
|
|
665
|
+
solanaClient,
|
|
666
|
+
fillInput,
|
|
667
|
+
svmRelayData,
|
|
668
|
+
mintInfo.data.decimals,
|
|
669
|
+
true,
|
|
670
|
+
remainingAccounts
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Creates a fill instruction with an instruction params PDA as the relayData input.
|
|
676
|
+
* @param spokePoolAddr Address of the spoke pool we're trying to fill through
|
|
677
|
+
* @param solanaClient RPC client to interact with Solana chain
|
|
678
|
+
* @param relayData RelayData instance, supplemented with destinationChainId
|
|
679
|
+
* @param signer signer associated with the relayer creating a Fill. Can be VoidSigner for gas estimation
|
|
680
|
+
* @param repaymentChainId Chain id where relayer repayment is desired
|
|
681
|
+
* @param repaymentAddress Address to which repayment will go to on repaymentChainId
|
|
682
|
+
* @returns FillRelay transaction
|
|
683
|
+
*/
|
|
684
|
+
export async function getIPFillRelayTx(
|
|
685
|
+
spokePoolAddr: SvmAddress,
|
|
686
|
+
solanaClient: SVMProvider,
|
|
687
|
+
relayData: Omit<RelayData, "recipient" | "outputToken"> & {
|
|
688
|
+
destinationChainId: number;
|
|
689
|
+
recipient: SvmAddress;
|
|
690
|
+
outputToken: SvmAddress;
|
|
691
|
+
},
|
|
692
|
+
signer: TransactionSigner,
|
|
693
|
+
repaymentChainId: number,
|
|
694
|
+
repaymentAddress: SdkAddress
|
|
695
|
+
) {
|
|
696
|
+
const program = toAddress(spokePoolAddr);
|
|
697
|
+
const _relayDataHash = getRelayDataHash(relayData, relayData.destinationChainId);
|
|
698
|
+
const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));
|
|
699
|
+
|
|
700
|
+
const [state, delegate, instructionParams] = await Promise.all([
|
|
701
|
+
getStatePda(program),
|
|
702
|
+
getFillRelayDelegatePda(relayDataHash, BigInt(repaymentChainId), toAddress(repaymentAddress), program),
|
|
703
|
+
getInstructionParamsPda(program, signer.address),
|
|
704
|
+
]);
|
|
705
|
+
|
|
706
|
+
const mint = toAddress(relayData.outputToken);
|
|
707
|
+
const mintInfo = await getMintInfo(solanaClient, mint);
|
|
708
|
+
|
|
709
|
+
const [recipientAta, relayerAta, fillStatus, eventAuthority] = await Promise.all([
|
|
710
|
+
getAssociatedTokenAddress(relayData.recipient, relayData.outputToken, mintInfo.programAddress),
|
|
711
|
+
getAssociatedTokenAddress(SvmAddress.from(signer.address), relayData.outputToken, mintInfo.programAddress),
|
|
712
|
+
getFillStatusPda(program, relayData, relayData.destinationChainId),
|
|
713
|
+
getEventAuthority(program),
|
|
714
|
+
]);
|
|
715
|
+
|
|
716
|
+
// Add remaining accounts if the relayData has a non-empty message.
|
|
717
|
+
// @dev ! since in the context of creating a `fillRelayTx`, `relayData` must be defined.
|
|
718
|
+
const remainingAccounts: (WritableAccount | ReadonlyAccount)[] = [];
|
|
719
|
+
if (relayData.message !== "0x") {
|
|
720
|
+
const acrossPlusMessage = deserializeMessage(relayData.message);
|
|
721
|
+
// The first `remainingAccount` _must_ be the handler address.
|
|
722
|
+
// https://github.com/across-protocol/contracts/blob/3310f8dc716407a5f97ef5fd2eae63df83251f2f/programs/svm-spoke/src/utils/message_utils.rs#L36.
|
|
723
|
+
remainingAccounts.push(getAccountMeta(acrossPlusMessage.handler, true));
|
|
724
|
+
remainingAccounts.push(
|
|
725
|
+
...acrossPlusMessage.accounts.map((account, idx) =>
|
|
726
|
+
getAccountMeta(account, idx < acrossPlusMessage.accounts.length - acrossPlusMessage.read_only_len)
|
|
727
|
+
)
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
const fillInput: SvmSpokeClient.FillRelayInput = {
|
|
732
|
+
signer: signer,
|
|
733
|
+
state,
|
|
734
|
+
delegate,
|
|
735
|
+
mint,
|
|
736
|
+
relayerTokenAccount: relayerAta,
|
|
737
|
+
recipientTokenAccount: recipientAta,
|
|
738
|
+
fillStatus,
|
|
739
|
+
tokenProgram: mintInfo.programAddress,
|
|
740
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
741
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
742
|
+
eventAuthority,
|
|
743
|
+
program,
|
|
744
|
+
instructionParams,
|
|
745
|
+
relayHash: relayDataHash,
|
|
746
|
+
relayData: null,
|
|
747
|
+
repaymentChainId: null,
|
|
748
|
+
repaymentAddress: null,
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
// Pass createRecipientAtaIfNeeded =true to the createFillInstruction function to create the recipient token account
|
|
752
|
+
// if it doesn't exist.
|
|
753
|
+
return createFillInstruction(
|
|
754
|
+
signer,
|
|
755
|
+
solanaClient,
|
|
756
|
+
fillInput,
|
|
757
|
+
{ outputAmount: relayData.outputAmount.toBigInt(), recipient: toAddress(relayData.recipient) },
|
|
758
|
+
mintInfo.data.decimals,
|
|
759
|
+
true,
|
|
760
|
+
remainingAccounts
|
|
761
|
+
);
|
|
640
762
|
}
|
|
641
763
|
|
|
642
764
|
/**
|
|
@@ -652,8 +774,10 @@ export const createFillInstruction = async (
|
|
|
652
774
|
signer: TransactionSigner,
|
|
653
775
|
solanaClient: SVMProvider,
|
|
654
776
|
fillInput: SvmSpokeClient.FillRelayInput,
|
|
777
|
+
relayData: Pick<SvmSpokeClient.RelayDataArgs, "outputAmount" | "recipient">,
|
|
655
778
|
tokenDecimals: number,
|
|
656
|
-
createRecipientAtaIfNeeded: boolean = true
|
|
779
|
+
createRecipientAtaIfNeeded: boolean = true,
|
|
780
|
+
remainingAccounts: (WritableAccount | ReadonlyAccount)[] = []
|
|
657
781
|
) => {
|
|
658
782
|
const mintInfo = await getMintInfo(solanaClient, fillInput.mint);
|
|
659
783
|
const approveIx = getApproveCheckedInstruction(
|
|
@@ -662,7 +786,7 @@ export const createFillInstruction = async (
|
|
|
662
786
|
mint: fillInput.mint,
|
|
663
787
|
delegate: fillInput.delegate,
|
|
664
788
|
owner: fillInput.signer,
|
|
665
|
-
amount:
|
|
789
|
+
amount: relayData.outputAmount,
|
|
666
790
|
decimals: tokenDecimals,
|
|
667
791
|
},
|
|
668
792
|
{
|
|
@@ -673,7 +797,7 @@ export const createFillInstruction = async (
|
|
|
673
797
|
const getCreateAssociatedTokenIdempotentIx = () =>
|
|
674
798
|
getCreateAssociatedTokenIdempotentInstruction({
|
|
675
799
|
payer: signer,
|
|
676
|
-
owner:
|
|
800
|
+
owner: relayData.recipient,
|
|
677
801
|
mint: fillInput.mint,
|
|
678
802
|
ata: fillInput.recipientTokenAccount,
|
|
679
803
|
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
@@ -682,6 +806,9 @@ export const createFillInstruction = async (
|
|
|
682
806
|
|
|
683
807
|
const createFillIx = SvmSpokeClient.getFillRelayInstruction(fillInput);
|
|
684
808
|
|
|
809
|
+
// Add remaining accounts.
|
|
810
|
+
createFillIx.accounts.push(...remainingAccounts);
|
|
811
|
+
|
|
685
812
|
return pipe(
|
|
686
813
|
await createDefaultTransaction(solanaClient, signer),
|
|
687
814
|
(tx) =>
|
|
@@ -691,6 +818,14 @@ export const createFillInstruction = async (
|
|
|
691
818
|
);
|
|
692
819
|
};
|
|
693
820
|
|
|
821
|
+
export function deserializeMessage(_message: string): AcrossPlusMessage {
|
|
822
|
+
const message = new Uint8Array(Buffer.from(_message.slice(2), "hex"));
|
|
823
|
+
// Add remaining accounts if the relayData has a non-empty message.
|
|
824
|
+
// @dev ! since in the context of creating a `fillRelayTx`, `relayData` must be defined.
|
|
825
|
+
const acrossPlusMessageDecoder = getAcrossPlusMessageDecoder();
|
|
826
|
+
return acrossPlusMessageDecoder.decode(message);
|
|
827
|
+
}
|
|
828
|
+
|
|
694
829
|
/**
|
|
695
830
|
* Creates a deposit instruction.
|
|
696
831
|
* @param signer - The signer of the transaction.
|
|
@@ -882,28 +1017,23 @@ export async function getAssociatedTokenAddress(
|
|
|
882
1017
|
}
|
|
883
1018
|
|
|
884
1019
|
export function getRelayDataHash(relayData: RelayData, destinationChainId: number): string {
|
|
885
|
-
|
|
1020
|
+
assert(relayData.message.startsWith("0x"), "Message must be a hex string");
|
|
886
1021
|
const uint64Encoder = getU64Encoder();
|
|
887
|
-
const uint32Encoder = getU32Encoder();
|
|
888
1022
|
|
|
889
|
-
|
|
890
|
-
const
|
|
1023
|
+
const svmRelayData = toSvmRelayData(relayData);
|
|
1024
|
+
const relayDataEncoder = SvmSpokeClient.getRelayDataEncoder();
|
|
1025
|
+
const encodedRelayData = relayDataEncoder.encode(svmRelayData);
|
|
1026
|
+
const encodedMessage = Buffer.from(relayData.message.slice(2), "hex");
|
|
891
1027
|
|
|
1028
|
+
// Reformat the encoded relay data the same way it is done in the SvmSpoke:
|
|
1029
|
+
// https://github.com/across-protocol/contracts/blob/3310f8dc716407a5f97ef5fd2eae63df83251f2f/programs/svm-spoke/src/utils/merkle_proof_utils.rs#L5
|
|
1030
|
+
const messageOffset = encodedRelayData.length - 4 - encodedMessage.length;
|
|
892
1031
|
const contentToHash = Buffer.concat([
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
encodeAddress(relayData.exclusiveRelayer),
|
|
896
|
-
encodeAddress(relayData.inputToken),
|
|
897
|
-
encodeAddress(relayData.outputToken),
|
|
898
|
-
arrayify(hexZeroPad(hexlify(relayData.inputAmount), 32)),
|
|
899
|
-
Uint8Array.from(uint64Encoder.encode(BigInt(relayData.outputAmount.toString()))),
|
|
900
|
-
Uint8Array.from(uint64Encoder.encode(BigInt(relayData.originChainId.toString()))),
|
|
901
|
-
arrayify(hexZeroPad(hexlify(relayData.depositId), 32)),
|
|
902
|
-
Uint8Array.from(uint32Encoder.encode(relayData.fillDeadline)),
|
|
903
|
-
Uint8Array.from(uint32Encoder.encode(relayData.exclusivityDeadline)),
|
|
904
|
-
hashNonEmptyMessage(Buffer.from(arrayify(relayData.message))),
|
|
1032
|
+
encodedRelayData.slice(0, messageOffset),
|
|
1033
|
+
hashNonEmptyMessage(encodedMessage),
|
|
905
1034
|
Uint8Array.from(uint64Encoder.encode(BigInt(destinationChainId))),
|
|
906
1035
|
]);
|
|
1036
|
+
|
|
907
1037
|
return keccak256(contentToHash);
|
|
908
1038
|
}
|
|
909
1039
|
|
|
@@ -991,6 +1121,47 @@ async function fetchBatchFillStatusFromPdaAccounts(
|
|
|
991
1121
|
return fillStatuses;
|
|
992
1122
|
}
|
|
993
1123
|
|
|
1124
|
+
/**
|
|
1125
|
+
* Returns a set of instructions to execute to fill a relay via instruction params.
|
|
1126
|
+
* @param spokePool The program ID of the Solana spoke pool.
|
|
1127
|
+
* @param relayData The relay data to write to the instruction params PDA.
|
|
1128
|
+
* @param signer The transaction signer and authority of the instruction params PDA.
|
|
1129
|
+
* @param maxWriteSize The maximum fragment size to write to instruction params.
|
|
1130
|
+
*/
|
|
1131
|
+
export async function getFillRelayViaInstructionParamsInstructions(
|
|
1132
|
+
spokePool: Address<string>,
|
|
1133
|
+
relayData: RelayData,
|
|
1134
|
+
signer: TransactionSigner<string>,
|
|
1135
|
+
maxWriteSize = 450
|
|
1136
|
+
): Promise<IInstruction[]> {
|
|
1137
|
+
const instructionParams = await getInstructionParamsPda(spokePool, signer.address);
|
|
1138
|
+
|
|
1139
|
+
const relayDataEncoder = SvmSpokeClient.getRelayDataEncoder();
|
|
1140
|
+
const svmRelayData = toSvmRelayData(relayData);
|
|
1141
|
+
const encodedRelayData = relayDataEncoder.encode(svmRelayData);
|
|
1142
|
+
|
|
1143
|
+
const initInstructionParamsIx = SvmSpokeClient.getInitializeInstructionParamsInstruction({
|
|
1144
|
+
signer,
|
|
1145
|
+
instructionParams,
|
|
1146
|
+
totalSize: encodedRelayData.length,
|
|
1147
|
+
});
|
|
1148
|
+
const instructions: IInstruction[] = [initInstructionParamsIx];
|
|
1149
|
+
|
|
1150
|
+
for (let i = 0; i <= encodedRelayData.length / maxWriteSize; ++i) {
|
|
1151
|
+
const offset = i * maxWriteSize;
|
|
1152
|
+
const offsetEnd = Math.min(offset + maxWriteSize, encodedRelayData.length);
|
|
1153
|
+
const fragment = encodedRelayData.slice(offset, offsetEnd);
|
|
1154
|
+
const writeInstructionParamsIx = SvmSpokeClient.getWriteInstructionParamsFragmentInstruction({
|
|
1155
|
+
signer,
|
|
1156
|
+
instructionParams,
|
|
1157
|
+
offset,
|
|
1158
|
+
fragment,
|
|
1159
|
+
});
|
|
1160
|
+
instructions.push(writeInstructionParamsIx);
|
|
1161
|
+
}
|
|
1162
|
+
return instructions;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
994
1165
|
/**
|
|
995
1166
|
* Returns the delegate PDA for deposit.
|
|
996
1167
|
*/
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountRole,
|
|
3
|
+
addDecoderSizePrefix,
|
|
4
|
+
addEncoderSizePrefix,
|
|
5
|
+
getAddressDecoder,
|
|
6
|
+
getAddressEncoder,
|
|
7
|
+
getArrayEncoder,
|
|
8
|
+
getArrayDecoder,
|
|
9
|
+
getBytesDecoder,
|
|
10
|
+
getBytesEncoder,
|
|
11
|
+
getStructDecoder,
|
|
12
|
+
getStructEncoder,
|
|
13
|
+
getU8Decoder,
|
|
14
|
+
getU8Encoder,
|
|
15
|
+
getU32Decoder,
|
|
16
|
+
getU32Encoder,
|
|
17
|
+
getU64Decoder,
|
|
18
|
+
getU64Encoder,
|
|
19
|
+
type Address,
|
|
20
|
+
type Decoder,
|
|
21
|
+
type Encoder,
|
|
22
|
+
type ReadonlyUint8Array,
|
|
23
|
+
type WritableAccount,
|
|
24
|
+
type ReadonlyAccount,
|
|
25
|
+
} from "@solana/kit";
|
|
26
|
+
|
|
27
|
+
export type AcrossPlusMessage = {
|
|
28
|
+
handler: Address;
|
|
29
|
+
read_only_len: number;
|
|
30
|
+
value_amount: bigint;
|
|
31
|
+
accounts: Array<Address>;
|
|
32
|
+
handler_message: ReadonlyUint8Array;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type CompiledIx = {
|
|
36
|
+
program_id_index: number;
|
|
37
|
+
account_key_indexes: Array<number>;
|
|
38
|
+
data: ReadonlyUint8Array;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function getAcrossPlusMessageEncoder(): Encoder<AcrossPlusMessage> {
|
|
42
|
+
return getStructEncoder([
|
|
43
|
+
["handler", getAddressEncoder()],
|
|
44
|
+
["read_only_len", getU8Encoder()],
|
|
45
|
+
["value_amount", getU64Encoder()],
|
|
46
|
+
["accounts", getArrayEncoder(getAddressEncoder())],
|
|
47
|
+
["handler_message", addEncoderSizePrefix(getBytesEncoder(), getU32Encoder())],
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getAcrossPlusMessageDecoder(): Decoder<AcrossPlusMessage> {
|
|
52
|
+
return getStructDecoder([
|
|
53
|
+
["handler", getAddressDecoder()],
|
|
54
|
+
["read_only_len", getU8Decoder()],
|
|
55
|
+
["value_amount", getU64Decoder()],
|
|
56
|
+
["accounts", getArrayDecoder(getAddressDecoder())],
|
|
57
|
+
["handler_message", addDecoderSizePrefix(getBytesDecoder(), getU32Decoder())],
|
|
58
|
+
]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function getHandlerMessageEncoder(): Encoder<Array<CompiledIx>> {
|
|
62
|
+
return getArrayEncoder(getCompiledIxEncoder());
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function getCompiledIxEncoder(): Encoder<CompiledIx> {
|
|
66
|
+
return getStructEncoder([
|
|
67
|
+
["program_id_index", getU8Encoder()],
|
|
68
|
+
["account_key_indexes", getArrayEncoder(getU8Encoder())],
|
|
69
|
+
["data", addEncoderSizePrefix(getBytesEncoder(), getU32Encoder())],
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function getCompiledIxDecoder(): Decoder<CompiledIx> {
|
|
74
|
+
return getStructDecoder([
|
|
75
|
+
["program_id_index", getU8Decoder()],
|
|
76
|
+
["account_key_indexes", getArrayDecoder(getU8Decoder())],
|
|
77
|
+
["data", addDecoderSizePrefix(getBytesDecoder(), getU32Decoder())],
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function getAccountMeta(value: Address, isWritable: boolean): WritableAccount | ReadonlyAccount {
|
|
82
|
+
return Object.freeze({
|
|
83
|
+
address: value,
|
|
84
|
+
role: isWritable ? AccountRole.WRITABLE : AccountRole.READONLY,
|
|
85
|
+
});
|
|
86
|
+
}
|
package/src/arch/svm/index.ts
CHANGED
package/src/arch/svm/utils.ts
CHANGED
|
@@ -507,6 +507,29 @@ export const getEmergencyDeleteRootBundleRootBundleId = (body: Buffer): number =
|
|
|
507
507
|
return result.rootBundleId.toNumber();
|
|
508
508
|
};
|
|
509
509
|
|
|
510
|
+
/**
|
|
511
|
+
* Converts a common `RelayData` type to an SvmSpokeClient.RelayData` type. This is useful for when we need
|
|
512
|
+
* to interface directly with the SvmSpoke.
|
|
513
|
+
* @param relayData The common RelayData TS type.
|
|
514
|
+
* @returns RelayData which conforms to the typing of the SvmSpoke.
|
|
515
|
+
*/
|
|
516
|
+
export function toSvmRelayData(relayData: RelayData): SvmSpokeClient.RelayData {
|
|
517
|
+
return {
|
|
518
|
+
originChainId: BigInt(relayData.originChainId),
|
|
519
|
+
depositor: address(relayData.depositor.toBase58()),
|
|
520
|
+
recipient: address(relayData.recipient.toBase58()),
|
|
521
|
+
depositId: ethers.utils.arrayify(ethers.utils.hexZeroPad(relayData.depositId.toHexString(), 32)),
|
|
522
|
+
inputToken: address(relayData.inputToken.toBase58()),
|
|
523
|
+
outputToken: address(relayData.outputToken.toBase58()),
|
|
524
|
+
inputAmount: ethers.utils.arrayify(ethers.utils.hexZeroPad(relayData.inputAmount.toHexString(), 32)),
|
|
525
|
+
outputAmount: relayData.outputAmount.toBigInt(),
|
|
526
|
+
message: Uint8Array.from(Buffer.from(relayData.message.slice(2), "hex")),
|
|
527
|
+
fillDeadline: relayData.fillDeadline,
|
|
528
|
+
exclusiveRelayer: address(relayData.exclusiveRelayer.toBase58()),
|
|
529
|
+
exclusivityDeadline: relayData.exclusivityDeadline,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
|
|
510
533
|
/**
|
|
511
534
|
* Convert a bigint (0 ≤ n < 2^256) to a 32-byte Uint8Array (big-endian).
|
|
512
535
|
* @param n The bigint to convert.
|