@solana/compat 2.0.0-experimental.ee4214c → 2.0.0-experimental.f7d1af1
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/index.browser.cjs +180 -1
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +179 -3
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +270 -6
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +179 -3
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +180 -1
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +179 -3
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +5 -2
- package/dist/types/address.d.ts +9 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/keypair.d.ts +8 -0
- package/dist/types/transaction.d.ts +2 -1
- package/package.json +13 -13
package/dist/index.node.js
CHANGED
|
@@ -1,8 +1,147 @@
|
|
|
1
1
|
import { pipe } from '@solana/functional';
|
|
2
2
|
import { AccountRole } from '@solana/instructions';
|
|
3
|
-
import { createTransaction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, appendTransactionInstruction } from '@solana/transactions';
|
|
3
|
+
import { createTransaction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, appendTransactionInstruction, isAdvanceNonceAccountInstruction, setTransactionLifetimeUsingDurableNonce } from '@solana/transactions';
|
|
4
4
|
|
|
5
|
-
// src/
|
|
5
|
+
// src/address.ts
|
|
6
|
+
function fromLegacyPublicKey(publicKey) {
|
|
7
|
+
return publicKey.toBase58();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/keypair.ts
|
|
11
|
+
function addPkcs8Header(bytes) {
|
|
12
|
+
return new Uint8Array([
|
|
13
|
+
/**
|
|
14
|
+
* PKCS#8 header
|
|
15
|
+
*/
|
|
16
|
+
48,
|
|
17
|
+
// ASN.1 sequence tag
|
|
18
|
+
46,
|
|
19
|
+
// Length of sequence (46 more bytes)
|
|
20
|
+
2,
|
|
21
|
+
// ASN.1 integer tag
|
|
22
|
+
1,
|
|
23
|
+
// Length of integer
|
|
24
|
+
0,
|
|
25
|
+
// Version number
|
|
26
|
+
48,
|
|
27
|
+
// ASN.1 sequence tag
|
|
28
|
+
5,
|
|
29
|
+
// Length of sequence
|
|
30
|
+
6,
|
|
31
|
+
// ASN.1 object identifier tag
|
|
32
|
+
3,
|
|
33
|
+
// Length of object identifier
|
|
34
|
+
// Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112
|
|
35
|
+
43,
|
|
36
|
+
// iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)
|
|
37
|
+
101,
|
|
38
|
+
// thawte(101)
|
|
39
|
+
// Ed25519 identifier
|
|
40
|
+
112,
|
|
41
|
+
// id-Ed25519(112)
|
|
42
|
+
/**
|
|
43
|
+
* Private key payload
|
|
44
|
+
*/
|
|
45
|
+
4,
|
|
46
|
+
// ASN.1 octet string tag
|
|
47
|
+
34,
|
|
48
|
+
// String length (34 more bytes)
|
|
49
|
+
// Private key bytes as octet string
|
|
50
|
+
4,
|
|
51
|
+
// ASN.1 octet string tag
|
|
52
|
+
32,
|
|
53
|
+
// String length (32 bytes)
|
|
54
|
+
...bytes
|
|
55
|
+
]);
|
|
56
|
+
}
|
|
57
|
+
async function fromLegacyKeypair(keypair, extractable) {
|
|
58
|
+
const publicKey = await crypto.subtle.importKey("raw", keypair.publicKey.toBytes(), "Ed25519", true, [
|
|
59
|
+
"verify"
|
|
60
|
+
]);
|
|
61
|
+
const privateKeyBytesPkcs8 = addPkcs8Header(keypair.secretKey.slice(0, 32));
|
|
62
|
+
const privateKey = await crypto.subtle.importKey(
|
|
63
|
+
"pkcs8",
|
|
64
|
+
privateKeyBytesPkcs8,
|
|
65
|
+
"Ed25519",
|
|
66
|
+
extractable ?? false,
|
|
67
|
+
["sign"]
|
|
68
|
+
);
|
|
69
|
+
return {
|
|
70
|
+
privateKey,
|
|
71
|
+
publicKey
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ../codecs-strings/dist/index.node.js
|
|
76
|
+
function assertValidBaseString(alphabet4, testValue, givenValue = testValue) {
|
|
77
|
+
if (!testValue.match(new RegExp(`^[${alphabet4}]*$`))) {
|
|
78
|
+
throw new Error(`Expected a string of base ${alphabet4.length}, got [${givenValue}].`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
var getBaseXEncoder = (alphabet4) => {
|
|
82
|
+
const base = alphabet4.length;
|
|
83
|
+
const baseBigInt = BigInt(base);
|
|
84
|
+
return {
|
|
85
|
+
description: `base${base}`,
|
|
86
|
+
encode(value) {
|
|
87
|
+
assertValidBaseString(alphabet4, value);
|
|
88
|
+
if (value === "")
|
|
89
|
+
return new Uint8Array();
|
|
90
|
+
const chars = [...value];
|
|
91
|
+
let trailIndex = chars.findIndex((c) => c !== alphabet4[0]);
|
|
92
|
+
trailIndex = trailIndex === -1 ? chars.length : trailIndex;
|
|
93
|
+
const leadingZeroes = Array(trailIndex).fill(0);
|
|
94
|
+
if (trailIndex === chars.length)
|
|
95
|
+
return Uint8Array.from(leadingZeroes);
|
|
96
|
+
const tailChars = chars.slice(trailIndex);
|
|
97
|
+
let base10Number = 0n;
|
|
98
|
+
let baseXPower = 1n;
|
|
99
|
+
for (let i = tailChars.length - 1; i >= 0; i -= 1) {
|
|
100
|
+
base10Number += baseXPower * BigInt(alphabet4.indexOf(tailChars[i]));
|
|
101
|
+
baseXPower *= baseBigInt;
|
|
102
|
+
}
|
|
103
|
+
const tailBytes = [];
|
|
104
|
+
while (base10Number > 0n) {
|
|
105
|
+
tailBytes.unshift(Number(base10Number % 256n));
|
|
106
|
+
base10Number /= 256n;
|
|
107
|
+
}
|
|
108
|
+
return Uint8Array.from(leadingZeroes.concat(tailBytes));
|
|
109
|
+
},
|
|
110
|
+
fixedSize: null,
|
|
111
|
+
maxSize: null
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
var alphabet2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
115
|
+
var getBase58Encoder = () => getBaseXEncoder(alphabet2);
|
|
116
|
+
|
|
117
|
+
// ../addresses/dist/index.node.js
|
|
118
|
+
var memoizedBase58Encoder;
|
|
119
|
+
function getMemoizedBase58Encoder() {
|
|
120
|
+
if (!memoizedBase58Encoder)
|
|
121
|
+
memoizedBase58Encoder = getBase58Encoder();
|
|
122
|
+
return memoizedBase58Encoder;
|
|
123
|
+
}
|
|
124
|
+
function assertIsAddress(putativeAddress) {
|
|
125
|
+
try {
|
|
126
|
+
if (
|
|
127
|
+
// Lowest address (32 bytes of zeroes)
|
|
128
|
+
putativeAddress.length < 32 || // Highest address (32 bytes of 255)
|
|
129
|
+
putativeAddress.length > 44
|
|
130
|
+
) {
|
|
131
|
+
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
132
|
+
}
|
|
133
|
+
const base58Encoder = getMemoizedBase58Encoder();
|
|
134
|
+
const bytes = base58Encoder.encode(putativeAddress);
|
|
135
|
+
const numBytes = bytes.byteLength;
|
|
136
|
+
if (numBytes !== 32) {
|
|
137
|
+
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
138
|
+
}
|
|
139
|
+
} catch (e2) {
|
|
140
|
+
throw new Error(`\`${putativeAddress}\` is not a base-58 encoded address`, {
|
|
141
|
+
cause: e2
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
6
145
|
function convertAccount(message, accountKeys, accountIndex) {
|
|
7
146
|
const accountPublicKey = accountKeys.get(accountIndex);
|
|
8
147
|
if (!accountPublicKey) {
|
|
@@ -66,7 +205,44 @@ function fromVersionedTransactionWithBlockhash(transaction, lastValidBlockHeight
|
|
|
66
205
|
(tx) => transaction.signatures.length ? { ...tx, signatures } : tx
|
|
67
206
|
);
|
|
68
207
|
}
|
|
208
|
+
function fromVersionedTransactionWithDurableNonce(transaction) {
|
|
209
|
+
if (transaction.message.addressTableLookups.length > 0) {
|
|
210
|
+
throw new Error("Cannot convert transaction with addressTableLookups");
|
|
211
|
+
}
|
|
212
|
+
const accountKeys = transaction.message.getAccountKeys();
|
|
213
|
+
const feePayer = accountKeys.staticAccountKeys[0];
|
|
214
|
+
if (!feePayer)
|
|
215
|
+
throw new Error("No fee payer set in VersionedTransaction");
|
|
216
|
+
const instructions = transaction.message.compiledInstructions.map(
|
|
217
|
+
(instruction) => convertInstruction(transaction.message, accountKeys, instruction)
|
|
218
|
+
);
|
|
219
|
+
if (instructions.length === 0) {
|
|
220
|
+
throw new Error("transaction with no instructions cannot be durable nonce transaction");
|
|
221
|
+
}
|
|
222
|
+
if (!isAdvanceNonceAccountInstruction(instructions[0])) {
|
|
223
|
+
throw new Error("transaction first instruction is not advance nonce account instruction");
|
|
224
|
+
}
|
|
225
|
+
const nonceAccountAddress = instructions[0].accounts[0].address;
|
|
226
|
+
assertIsAddress(nonceAccountAddress);
|
|
227
|
+
const nonceAuthorityAddress = instructions[0].accounts[2].address;
|
|
228
|
+
assertIsAddress(nonceAuthorityAddress);
|
|
229
|
+
const durableNonceLifetime = {
|
|
230
|
+
nonce: transaction.message.recentBlockhash,
|
|
231
|
+
nonceAccountAddress,
|
|
232
|
+
nonceAuthorityAddress
|
|
233
|
+
};
|
|
234
|
+
const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);
|
|
235
|
+
return pipe(
|
|
236
|
+
createTransaction({ version: transaction.version }),
|
|
237
|
+
(tx) => setTransactionFeePayer(feePayer.toBase58(), tx),
|
|
238
|
+
(tx) => setTransactionLifetimeUsingDurableNonce(durableNonceLifetime, tx),
|
|
239
|
+
(tx) => instructions.slice(1).reduce((acc, instruction) => {
|
|
240
|
+
return appendTransactionInstruction(instruction, acc);
|
|
241
|
+
}, tx),
|
|
242
|
+
(tx) => transaction.signatures.length ? { ...tx, signatures } : tx
|
|
243
|
+
);
|
|
244
|
+
}
|
|
69
245
|
|
|
70
|
-
export { fromVersionedTransactionWithBlockhash };
|
|
246
|
+
export { fromLegacyKeypair, fromLegacyPublicKey, fromVersionedTransactionWithBlockhash, fromVersionedTransactionWithDurableNonce };
|
|
71
247
|
//# sourceMappingURL=out.js.map
|
|
72
248
|
//# sourceMappingURL=index.node.js.map
|
package/dist/index.node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transaction.ts"],"names":[],"mappings":";AACA,SAAS,YAAY;AAErB,SAAS,mBAAmB;AAS5B;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AASP,SAAS,eACL,SACA,aACA,cACY;AACZ,QAAM,mBAAmB,YAAY,IAAI,YAAY;AACrD,MAAI,CAAC,kBAAkB;AAEnB,UAAM,IAAI,MAAM,2CAA2C,YAAY,EAAE;AAAA,EAC7E;AACA,QAAM,WAAW,QAAQ,gBAAgB,YAAY;AACrD,QAAM,aAAa,QAAQ,kBAAkB,YAAY;AAEzD,QAAM,OAAO,WACP,aACI,YAAY,kBACZ,YAAY,kBAChB,aACA,YAAY,WACZ,YAAY;AAElB,SAAO;AAAA,IACH,SAAS,iBAAiB,SAAS;AAAA,IACnC;AAAA,EACJ;AACJ;AAEA,SAAS,mBACL,SACA,aACA,aACY;AACZ,QAAM,0BAA0B,YAAY,IAAI,YAAY,cAAc;AAC1E,MAAI,CAAC,yBAAyB;AAE1B,UAAM,IAAI,MAAM,2CAA2C,YAAY,cAAc,EAAE;AAAA,EAC3F;AAEA,QAAM,WAAW,YAAY,kBAAkB;AAAA,IAAI,kBAC/C,eAAe,SAAS,aAAa,YAAY;AAAA,EACrD;AAEA,SAAO;AAAA,IACH,gBAAgB,wBAAwB,SAAS;AAAA,IACjD,GAAI,SAAS,SAAS,EAAE,SAAS,IAAI,CAAC;AAAA,IACtC,GAAI,YAAY,KAAK,SAAS,EAAE,MAAM,YAAY,KAAK,IAAI,CAAC;AAAA,EAChE;AACJ;AAEA,SAAS,kBACL,aACA,mBACwC;AACxC,SAAO,YAAY,WAAW,OAAO,CAAC,KAAK,KAAK,UAAU;AAGtD,UAAM,WAAW,IAAI,MAAM,UAAQ,SAAS,CAAC;AAC7C,QAAI;AAAU,aAAO;AAErB,UAAM,UAAU,kBAAkB,KAAK,EAAE,SAAS;AAClD,WAAO,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAwB;AAAA,EACxD,GAAG,CAAC,CAAC;AACT;AAEO,SAAS,sCACZ,aACA,sBAC0E;AAI1E,MAAI,YAAY,QAAQ,oBAAoB,SAAS,GAAG;AAEpD,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACzE;AAEA,QAAM,cAAc,YAAY,QAAQ,eAAe;AAGvD,QAAM,WAAW,YAAY,kBAAkB,CAAC;AAEhD,MAAI,CAAC;AAAU,UAAM,IAAI,MAAM,0CAA0C;AAGzE,QAAM,oBAAoB;AAAA,IACtB,WAAW,YAAY,QAAQ;AAAA,IAC/B,sBAAsB,wBAAwB,MAAM,MAAM;AAAA;AAAA,EAC9D;AAEA,QAAM,eAAe,YAAY,QAAQ,qBAAqB;AAAA,IAAI,iBAC9D,mBAAmB,YAAY,SAAS,aAAa,WAAW;AAAA,EACpE;AAEA,QAAM,aAAa,kBAAkB,aAAa,YAAY,iBAAiB;AAE/E,SAAO;AAAA,IACH,kBAAkB,EAAE,SAAS,YAAY,QAAQ,CAAC;AAAA,IAClD,QAAM,uBAAuB,SAAS,SAAS,GAA2B,EAAE;AAAA,IAC5E,QAAM,qCAAqC,mBAAmB,EAAE;AAAA,IAChE,QACI,aAAa,OAAO,CAAC,KAAK,gBAAgB;AACtC,aAAO,6BAA6B,aAAa,GAAG;AAAA,IACxD,GAAG,EAAE;AAAA,IACT,QAAO,YAAY,WAAW,SAAS,EAAE,GAAG,IAAI,WAAW,IAAI;AAAA,EACnE;AACJ","sourcesContent":["import type { Base58EncodedAddress } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport type { IAccountMeta, IInstruction } from '@solana/instructions';\nimport { AccountRole } from '@solana/instructions';\nimport type { Ed25519Signature } from '@solana/keys';\nimport type {\n Blockhash,\n ITransactionWithBlockhashLifetime,\n ITransactionWithFeePayer,\n ITransactionWithSignatures,\n Transaction,\n} from '@solana/transactions';\nimport {\n appendTransactionInstruction,\n createTransaction,\n setTransactionFeePayer,\n setTransactionLifetimeUsingBlockhash,\n} from '@solana/transactions';\nimport type {\n MessageAccountKeys,\n MessageCompiledInstruction,\n PublicKey,\n VersionedMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nfunction convertAccount(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n accountIndex: number\n): IAccountMeta {\n const accountPublicKey = accountKeys.get(accountIndex);\n if (!accountPublicKey) {\n // TODO coded error\n throw new Error(`Could not find account address at index ${accountIndex}`);\n }\n const isSigner = message.isAccountSigner(accountIndex);\n const isWritable = message.isAccountWritable(accountIndex);\n\n const role = isSigner\n ? isWritable\n ? AccountRole.WRITABLE_SIGNER\n : AccountRole.READONLY_SIGNER\n : isWritable\n ? AccountRole.WRITABLE\n : AccountRole.READONLY;\n\n return {\n address: accountPublicKey.toBase58() as Base58EncodedAddress,\n role,\n };\n}\n\nfunction convertInstruction(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n instruction: MessageCompiledInstruction\n): IInstruction {\n const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);\n if (!programAddressPublicKey) {\n // TODO coded error\n throw new Error(`Could not find program address at index ${instruction.programIdIndex}`);\n }\n\n const accounts = instruction.accountKeyIndexes.map(accountIndex =>\n convertAccount(message, accountKeys, accountIndex)\n );\n\n return {\n programAddress: programAddressPublicKey.toBase58() as Base58EncodedAddress,\n ...(accounts.length ? { accounts } : {}),\n ...(instruction.data.length ? { data: instruction.data } : {}),\n };\n}\n\nfunction convertSignatures(\n transaction: VersionedTransaction,\n staticAccountKeys: PublicKey[]\n): ITransactionWithSignatures['signatures'] {\n return transaction.signatures.reduce((acc, sig, index) => {\n // legacy web3js includes a fake all 0 signature if it hasn't been signed\n // we don't do that for the new tx model. So just skip if it's all 0s\n const allZeros = sig.every(byte => byte === 0);\n if (allZeros) return acc;\n\n const address = staticAccountKeys[index].toBase58() as Base58EncodedAddress;\n return { ...acc, [address]: sig as Ed25519Signature };\n }, {});\n}\n\nexport function fromVersionedTransactionWithBlockhash(\n transaction: VersionedTransaction,\n lastValidBlockHeight?: bigint\n): Transaction & ITransactionWithFeePayer & ITransactionWithBlockhashLifetime {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n // TODO: coded error\n if (!feePayer) throw new Error('No fee payer set in VersionedTransaction');\n\n // TOOD: add support for durable nonce transactions\n const blockhashLifetime = {\n blockhash: transaction.message.recentBlockhash as Blockhash,\n lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n, // U64 MAX\n };\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction)\n );\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Base58EncodedAddress, tx),\n tx => setTransactionLifetimeUsingBlockhash(blockhashLifetime, tx),\n tx =>\n instructions.reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx)\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/address.ts","../src/keypair.ts","../../codecs-strings/src/assertions.ts","../../codecs-strings/src/baseX.ts","../../codecs-strings/src/base16.ts","../../codecs-strings/src/base64.ts","../../addresses/src/address.ts","../src/transaction.ts"],"names":["alphabet","e"],"mappings":"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","sourcesContent":["import { Address } from '@solana/addresses';\nimport { PublicKey } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS PublicKey to a base58 encoded address\n * @param publicKey The PublicKey to convert\n * @returns An Address\n */\nexport function fromLegacyPublicKey<TAddress extends string>(publicKey: PublicKey): Address<TAddress> {\n return publicKey.toBase58() as Address<TAddress>;\n}\n","import { Keypair } from '@solana/web3.js';\n\nfunction addPkcs8Header(bytes: Uint8Array): Uint8Array {\n // prettier-ignore\n return new Uint8Array([\n /**\n * PKCS#8 header\n */\n 0x30, // ASN.1 sequence tag\n 0x2e, // Length of sequence (46 more bytes)\n\n 0x02, // ASN.1 integer tag\n 0x01, // Length of integer\n 0x00, // Version number\n\n 0x30, // ASN.1 sequence tag\n 0x05, // Length of sequence\n 0x06, // ASN.1 object identifier tag\n 0x03, // Length of object identifier\n // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n 0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n 0x65, // thawte(101)\n // Ed25519 identifier\n 0x70, // id-Ed25519(112)\n\n /**\n * Private key payload\n */\n 0x04, // ASN.1 octet string tag\n 0x22, // String length (34 more bytes)\n\n // Private key bytes as octet string\n 0x04, // ASN.1 octet string tag\n 0x20, // String length (32 bytes)\n\n ...bytes\n ]);\n}\n\n/**\n * Convert from a Legacy Web3 JS Keypair to a CryptoKeyPair\n * @param keypair The Keypair to convert\n * @returns A CryptoKeyPair\n */\nexport async function fromLegacyKeypair(keypair: Keypair, extractable?: boolean): Promise<CryptoKeyPair> {\n const publicKey: CryptoKey = await crypto.subtle.importKey('raw', keypair.publicKey.toBytes(), 'Ed25519', true, [\n 'verify',\n ]);\n const privateKeyBytesPkcs8 = addPkcs8Header(keypair.secretKey.slice(0, 32));\n const privateKey: CryptoKey = await crypto.subtle.importKey(\n 'pkcs8',\n privateKeyBytesPkcs8,\n 'Ed25519',\n extractable ?? false,\n ['sign']\n );\n return {\n privateKey,\n publicKey,\n } as CryptoKeyPair;\n}\n","/**\n * Asserts that a given string matches a given alphabet.\n */\nexport function assertValidBaseString(alphabet: string, testValue: string, givenValue = testValue) {\n if (!testValue.match(new RegExp(`^[${alphabet}]*$`))) {\n // TODO: Coded error.\n throw new Error(`Expected a string of base ${alphabet.length}, got [${givenValue}].`);\n }\n}\n","import { Codec, combineCodec, Decoder, Encoder } from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/**\n * Encodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXEncoder = (alphabet: string): Encoder<string> => {\n const base = alphabet.length;\n const baseBigInt = BigInt(base);\n return {\n description: `base${base}`,\n encode(value: string): Uint8Array {\n // Check if the value is valid.\n assertValidBaseString(alphabet, value);\n if (value === '') return new Uint8Array();\n\n // Handle leading zeroes.\n const chars = [...value];\n let trailIndex = chars.findIndex(c => c !== alphabet[0]);\n trailIndex = trailIndex === -1 ? chars.length : trailIndex;\n const leadingZeroes = Array(trailIndex).fill(0);\n if (trailIndex === chars.length) return Uint8Array.from(leadingZeroes);\n\n // From baseX to base10.\n const tailChars = chars.slice(trailIndex);\n let base10Number = 0n;\n let baseXPower = 1n;\n for (let i = tailChars.length - 1; i >= 0; i -= 1) {\n base10Number += baseXPower * BigInt(alphabet.indexOf(tailChars[i]));\n baseXPower *= baseBigInt;\n }\n\n // From base10 to bytes.\n const tailBytes = [];\n while (base10Number > 0n) {\n tailBytes.unshift(Number(base10Number % 256n));\n base10Number /= 256n;\n }\n return Uint8Array.from(leadingZeroes.concat(tailBytes));\n },\n fixedSize: null,\n maxSize: null,\n };\n};\n\n/**\n * Decodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXDecoder = (alphabet: string): Decoder<string> => {\n const base = alphabet.length;\n const baseBigInt = BigInt(base);\n return {\n decode(rawBytes, offset = 0): [string, number] {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0) return ['', 0];\n\n // Handle leading zeroes.\n let trailIndex = bytes.findIndex(n => n !== 0);\n trailIndex = trailIndex === -1 ? bytes.length : trailIndex;\n const leadingZeroes = alphabet[0].repeat(trailIndex);\n if (trailIndex === bytes.length) return [leadingZeroes, rawBytes.length];\n\n // From bytes to base10.\n let base10Number = bytes.slice(trailIndex).reduce((sum, byte) => sum * 256n + BigInt(byte), 0n);\n\n // From base10 to baseX.\n const tailChars = [];\n while (base10Number > 0n) {\n tailChars.unshift(alphabet[Number(base10Number % baseBigInt)]);\n base10Number /= baseBigInt;\n }\n\n return [leadingZeroes + tailChars.join(''), rawBytes.length];\n },\n description: `base${base}`,\n fixedSize: null,\n maxSize: null,\n };\n};\n\n/**\n * A string codec that requires a custom alphabet and uses\n * the length of that alphabet as the base. It then divides\n * the input by the base as many times as necessary to get\n * the output. It also supports leading zeroes by using the\n * first character of the alphabet as the zero character.\n *\n * This can be used to create codecs such as base10 or base58.\n */\nexport const getBaseXCodec = (alphabet: string): Codec<string> =>\n combineCodec(getBaseXEncoder(alphabet), getBaseXDecoder(alphabet));\n","import { Codec, combineCodec, Decoder, Encoder } from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/** Encodes strings in base16. */\nexport const getBase16Encoder = (): Encoder<string> => ({\n description: 'base16',\n encode(value: string) {\n const lowercaseValue = value.toLowerCase();\n assertValidBaseString('0123456789abcdef', lowercaseValue, value);\n const matches = lowercaseValue.match(/.{1,2}/g);\n return Uint8Array.from(matches ? matches.map((byte: string) => parseInt(byte, 16)) : []);\n },\n fixedSize: null,\n maxSize: null,\n});\n\n/** Decodes strings in base16. */\nexport const getBase16Decoder = (): Decoder<string> => ({\n decode(bytes, offset = 0) {\n const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n return [value, bytes.length];\n },\n description: 'base16',\n fixedSize: null,\n maxSize: null,\n});\n\n/** Encodes and decodes strings in base16. */\nexport const getBase16Codec = (): Codec<string> => combineCodec(getBase16Encoder(), getBase16Decoder());\n","import { combineCodec, Decoder, Encoder, mapDecoder, mapEncoder } from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\nimport { getBaseXResliceDecoder, getBaseXResliceEncoder } from './baseX-reslice';\n\nconst alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n/** Encodes strings in base64. */\nexport const getBase64Encoder = (): Encoder<string> => {\n if (__BROWSER__) {\n return {\n description: `base64`,\n encode(value: string): Uint8Array {\n try {\n const bytes = (atob as Window['atob'])(value)\n .split('')\n .map(c => c.charCodeAt(0));\n return new Uint8Array(bytes);\n } catch (e) {\n // TODO: Coded error.\n throw new Error(`Expected a string of base 64, got [${value}].`);\n }\n },\n fixedSize: null,\n maxSize: null,\n };\n }\n\n if (__NODEJS__) {\n return {\n description: `base64`,\n encode(value: string): Uint8Array {\n assertValidBaseString(alphabet, value.replace(/=/g, ''));\n return new Uint8Array(Buffer.from(value, 'base64'));\n },\n fixedSize: null,\n maxSize: null,\n };\n }\n\n return mapEncoder(getBaseXResliceEncoder(alphabet, 6), (value: string): string => value.replace(/=/g, ''));\n};\n\n/** Decodes strings in base64. */\nexport const getBase64Decoder = (): Decoder<string> => {\n if (__BROWSER__) {\n return {\n decode(bytes, offset = 0) {\n const slice = bytes.slice(offset);\n const value = (btoa as Window['btoa'])(String.fromCharCode(...slice));\n return [value, bytes.length];\n },\n description: `base64`,\n fixedSize: null,\n maxSize: null,\n };\n }\n\n if (__NODEJS__) {\n return {\n decode: (bytes, offset = 0) => [Buffer.from(bytes, offset).toString('base64'), bytes.length],\n description: `base64`,\n fixedSize: null,\n maxSize: null,\n };\n }\n\n return mapDecoder(getBaseXResliceDecoder(alphabet, 6), (value: string): string =>\n value.padEnd(Math.ceil(value.length / 4) * 4, '=')\n );\n};\n\n/** Encodes and decodes strings in base64. */\nexport const getBase64Codec = () => combineCodec(getBase64Encoder(), getBase64Decoder());\n","import { Codec, combineCodec, Decoder, Encoder, mapEncoder } from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder, getStringDecoder, getStringEncoder } from '@solana/codecs-strings';\n\nexport type Address<TAddress extends string = string> = TAddress & {\n readonly __brand: unique symbol;\n};\n\nlet memoizedBase58Encoder: Encoder<string> | undefined;\nlet memoizedBase58Decoder: Decoder<string> | undefined;\n\nfunction getMemoizedBase58Encoder(): Encoder<string> {\n if (!memoizedBase58Encoder) memoizedBase58Encoder = getBase58Encoder();\n return memoizedBase58Encoder;\n}\n\nfunction getMemoizedBase58Decoder(): Decoder<string> {\n if (!memoizedBase58Decoder) memoizedBase58Decoder = getBase58Decoder();\n return memoizedBase58Decoder;\n}\n\nexport function isAddress(putativeAddress: string): putativeAddress is Address<typeof putativeAddress> {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n return false;\n }\n return true;\n}\n\nexport function assertIsAddress(putativeAddress: string): asserts putativeAddress is Address<typeof putativeAddress> {\n try {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n throw new Error('Expected input string to decode to a byte array of length 32.');\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);\n }\n } catch (e) {\n throw new Error(`\\`${putativeAddress}\\` is not a base-58 encoded address`, {\n cause: e,\n });\n }\n}\n\nexport function address<TAddress extends string = string>(putativeAddress: TAddress): Address<TAddress> {\n assertIsAddress(putativeAddress);\n return putativeAddress as Address<TAddress>;\n}\n\nexport function getAddressEncoder(config?: Readonly<{ description: string }>): Encoder<Address> {\n return mapEncoder(\n getStringEncoder({\n description: config?.description ?? 'Address',\n encoding: getMemoizedBase58Encoder(),\n size: 32,\n }),\n putativeAddress => address(putativeAddress)\n );\n}\n\nexport function getAddressDecoder(config?: Readonly<{ description: string }>): Decoder<Address> {\n return getStringDecoder({\n description: config?.description ?? 'Address',\n encoding: getMemoizedBase58Decoder(),\n size: 32,\n }) as Decoder<Address>;\n}\n\nexport function getAddressCodec(config?: Readonly<{ description: string }>): Codec<Address> {\n return combineCodec(getAddressEncoder(config), getAddressDecoder(config));\n}\n\nexport function getAddressComparator(): (x: string, y: string) => number {\n return new Intl.Collator('en', {\n caseFirst: 'lower',\n ignorePunctuation: false,\n localeMatcher: 'best fit',\n numeric: false,\n sensitivity: 'variant',\n usage: 'sort',\n }).compare;\n}\n","import { type Address, assertIsAddress } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport type { IAccountMeta, IInstruction } from '@solana/instructions';\nimport { AccountRole } from '@solana/instructions';\nimport type { SignatureBytes } from '@solana/keys';\nimport {\n appendTransactionInstruction,\n type Blockhash,\n createTransaction,\n type IDurableNonceTransaction,\n isAdvanceNonceAccountInstruction,\n type ITransactionWithBlockhashLifetime,\n type ITransactionWithFeePayer,\n type ITransactionWithSignatures,\n type Nonce,\n setTransactionFeePayer,\n setTransactionLifetimeUsingBlockhash,\n setTransactionLifetimeUsingDurableNonce,\n type Transaction,\n} from '@solana/transactions';\nimport type {\n MessageAccountKeys,\n MessageCompiledInstruction,\n PublicKey,\n VersionedMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nfunction convertAccount(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n accountIndex: number\n): IAccountMeta {\n const accountPublicKey = accountKeys.get(accountIndex);\n if (!accountPublicKey) {\n // TODO coded error\n throw new Error(`Could not find account address at index ${accountIndex}`);\n }\n const isSigner = message.isAccountSigner(accountIndex);\n const isWritable = message.isAccountWritable(accountIndex);\n\n const role = isSigner\n ? isWritable\n ? AccountRole.WRITABLE_SIGNER\n : AccountRole.READONLY_SIGNER\n : isWritable\n ? AccountRole.WRITABLE\n : AccountRole.READONLY;\n\n return {\n address: accountPublicKey.toBase58() as Address,\n role,\n };\n}\n\nfunction convertInstruction(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n instruction: MessageCompiledInstruction\n): IInstruction {\n const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);\n if (!programAddressPublicKey) {\n // TODO coded error\n throw new Error(`Could not find program address at index ${instruction.programIdIndex}`);\n }\n\n const accounts = instruction.accountKeyIndexes.map(accountIndex =>\n convertAccount(message, accountKeys, accountIndex)\n );\n\n return {\n programAddress: programAddressPublicKey.toBase58() as Address,\n ...(accounts.length ? { accounts } : {}),\n ...(instruction.data.length ? { data: instruction.data } : {}),\n };\n}\n\nfunction convertSignatures(\n transaction: VersionedTransaction,\n staticAccountKeys: PublicKey[]\n): ITransactionWithSignatures['signatures'] {\n return transaction.signatures.reduce((acc, sig, index) => {\n // legacy web3js includes a fake all 0 signature if it hasn't been signed\n // we don't do that for the new tx model. So just skip if it's all 0s\n const allZeros = sig.every(byte => byte === 0);\n if (allZeros) return acc;\n\n const address = staticAccountKeys[index].toBase58() as Address;\n return { ...acc, [address]: sig as SignatureBytes };\n }, {});\n}\n\nexport function fromVersionedTransactionWithBlockhash(\n transaction: VersionedTransaction,\n lastValidBlockHeight?: bigint\n): Transaction & ITransactionWithFeePayer & ITransactionWithBlockhashLifetime {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n // TODO: coded error\n if (!feePayer) throw new Error('No fee payer set in VersionedTransaction');\n\n const blockhashLifetime = {\n blockhash: transaction.message.recentBlockhash as Blockhash,\n lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n, // U64 MAX\n };\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction)\n );\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingBlockhash(blockhashLifetime, tx),\n tx =>\n instructions.reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx)\n );\n}\n\nexport function fromVersionedTransactionWithDurableNonce(\n transaction: VersionedTransaction\n): Transaction & ITransactionWithFeePayer & IDurableNonceTransaction {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n // TODO: coded error\n if (!feePayer) throw new Error('No fee payer set in VersionedTransaction');\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction)\n );\n\n // Check first instruction is durable nonce + extract params\n if (instructions.length === 0) {\n // TODO: coded error\n throw new Error('transaction with no instructions cannot be durable nonce transaction');\n }\n\n if (!isAdvanceNonceAccountInstruction(instructions[0])) {\n // TODO: coded error\n throw new Error('transaction first instruction is not advance nonce account instruction');\n }\n\n // We know these accounts are defined because we checked `isAdvanceNonceAccountInstruction`\n const nonceAccountAddress = instructions[0].accounts![0].address;\n assertIsAddress(nonceAccountAddress);\n\n const nonceAuthorityAddress = instructions[0].accounts![2].address;\n assertIsAddress(nonceAuthorityAddress);\n\n const durableNonceLifetime = {\n nonce: transaction.message.recentBlockhash as Nonce,\n nonceAccountAddress,\n nonceAuthorityAddress,\n };\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingDurableNonce(durableNonceLifetime, tx),\n tx =>\n instructions.slice(1).reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx)\n );\n}\n"]}
|
|
@@ -2,9 +2,12 @@ this.globalThis = this.globalThis || {};
|
|
|
2
2
|
this.globalThis.solanaWeb3 = (function (exports) {
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
function
|
|
5
|
+
function $(e){return e.toBase58()}function R(e){return new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32,...e])}async function Y(e,n){let r=await crypto.subtle.importKey("raw",e.publicKey.toBytes(),"Ed25519",!0,["verify"]),t=R(e.secretKey.slice(0,32));return {privateKey:await crypto.subtle.importKey("pkcs8",t,"Ed25519",n??!1,["sign"]),publicKey:r}}function z(e,n,r=n){if(!n.match(new RegExp(`^[${e}]*$`)))throw new Error(`Expected a string of base ${e.length}, got [${r}].`)}var N=e=>{let n=e.length,r=BigInt(n);return {description:`base${n}`,encode(t){if(z(e,t),t==="")return new Uint8Array;let o=[...t],s=o.findIndex(f=>f!==e[0]);s=s===-1?o.length:s;let a=Array(s).fill(0);if(s===o.length)return Uint8Array.from(a);let i=o.slice(s),c=0n,u=1n;for(let f=i.length-1;f>=0;f-=1)c+=u*BigInt(e.indexOf(i[f])),u*=r;let p=[];for(;c>0n;)p.unshift(Number(c%256n)),c/=256n;return Uint8Array.from(a.concat(p))},fixedSize:null,maxSize:null}};var C="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",I=()=>N(C);var b;function _(){return b||(b=I()),b}function A(e){try{if(e.length<32||e.length>44)throw new Error("Expected input string to decode to a byte array of length 32.");let t=_().encode(e).byteLength;if(t!==32)throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${t}`)}catch(n){throw new Error(`\`${e}\` is not a base-58 encoded address`,{cause:n})}}function y(e,...n){return n.reduce((r,t)=>t(r),e)}var l=(e=>(e[e.WRITABLE_SIGNER=3]="WRITABLE_SIGNER",e[e.READONLY_SIGNER=2]="READONLY_SIGNER",e[e.WRITABLE=1]="WRITABLE",e[e.READONLY=0]="READONLY",e))(l||{});function m(e){if("signatures"in e){let{signatures:n,...r}=e;return r}else return e}function v(e,n){if("lifetimeConstraint"in n&&n.lifetimeConstraint.blockhash===e.blockhash&&n.lifetimeConstraint.lastValidBlockHeight===e.lastValidBlockHeight)return n;let r={...m(n),lifetimeConstraint:e};return Object.freeze(r),r}function E({version:e}){let n={instructions:[],version:e};return Object.freeze(n),n}var g=(e=>(e[e.WRITABLE_SIGNER=3]="WRITABLE_SIGNER",e[e.READONLY_SIGNER=2]="READONLY_SIGNER",e[e.WRITABLE=1]="WRITABLE",e[e.READONLY=0]="READONLY",e))(g||{});function P(e){return e>=2}var x="SysvarRecentB1ockHashes11111111111111111111",D="11111111111111111111111111111111";function S(e,n){return {accounts:[{address:e,role:g.WRITABLE},{address:x,role:g.READONLY},{address:n,role:g.READONLY_SIGNER}],data:new Uint8Array([4,0,0,0]),programAddress:D}}function h(e){return e.programAddress===D&&e.data!=null&&K(e.data)&&e.accounts?.length===3&&e.accounts[0].address!=null&&e.accounts[0].role===g.WRITABLE&&e.accounts[1].address===x&&e.accounts[1].role===g.READONLY&&e.accounts[2].address!=null&&P(e.accounts[2].role)}function K(e){return e.byteLength===4&&e[0]===4&&e[1]===0&&e[2]===0&&e[3]===0}function M(e){return "lifetimeConstraint"in e&&typeof e.lifetimeConstraint.nonce=="string"&&e.instructions[0]!=null&&h(e.instructions[0])}function U(e,n,r){return e.accounts[0].address===n&&e.accounts[2].address===r}function B({nonce:e,nonceAccountAddress:n,nonceAuthorityAddress:r},t){let o,s=t.instructions[0];if(s&&h(s))if(U(s,n,r)){if(M(t)&&t.lifetimeConstraint.nonce===e)return t;o=[s,...t.instructions.slice(1)];}else o=[S(n,r),...t.instructions.slice(1)];else o=[S(n,r),...t.instructions];let a={...m(t),instructions:o,lifetimeConstraint:{nonce:e}};return Object.freeze(a),a}function T(e,n){if("feePayer"in n&&e===n.feePayer)return n;let r={...m(n),feePayer:e};return Object.freeze(r),r}function w(e,n){let r={...m(n),instructions:[...n.instructions,e]};return Object.freeze(r),r}function O(e,n,r){let t=n.get(r);if(!t)throw new Error(`Could not find account address at index ${r}`);let o=e.isAccountSigner(r),s=e.isAccountWritable(r),a=o?s?l.WRITABLE_SIGNER:l.READONLY_SIGNER:s?l.WRITABLE:l.READONLY;return {address:t.toBase58(),role:a}}function k(e,n,r){let t=n.get(r.programIdIndex);if(!t)throw new Error(`Could not find program address at index ${r.programIdIndex}`);let o=r.accountKeyIndexes.map(s=>O(e,n,s));return {programAddress:t.toBase58(),...o.length?{accounts:o}:{},...r.data.length?{data:r.data}:{}}}function L(e,n){return e.signatures.reduce((r,t,o)=>{if(t.every(i=>i===0))return r;let a=n[o].toBase58();return {...r,[a]:t}},{})}function me(e,n){if(e.message.addressTableLookups.length>0)throw new Error("Cannot convert transaction with addressTableLookups");let r=e.message.getAccountKeys(),t=r.staticAccountKeys[0];if(!t)throw new Error("No fee payer set in VersionedTransaction");let o={blockhash:e.message.recentBlockhash,lastValidBlockHeight:n??2n**64n-1n},s=e.message.compiledInstructions.map(i=>k(e.message,r,i)),a=L(e,r.staticAccountKeys);return y(E({version:e.version}),i=>T(t.toBase58(),i),i=>v(o,i),i=>s.reduce((c,u)=>w(u,c),i),i=>e.signatures.length?{...i,signatures:a}:i)}function he(e){if(e.message.addressTableLookups.length>0)throw new Error("Cannot convert transaction with addressTableLookups");let n=e.message.getAccountKeys(),r=n.staticAccountKeys[0];if(!r)throw new Error("No fee payer set in VersionedTransaction");let t=e.message.compiledInstructions.map(c=>k(e.message,n,c));if(t.length===0)throw new Error("transaction with no instructions cannot be durable nonce transaction");if(!h(t[0]))throw new Error("transaction first instruction is not advance nonce account instruction");let o=t[0].accounts[0].address;A(o);let s=t[0].accounts[2].address;A(s);let a={nonce:e.message.recentBlockhash,nonceAccountAddress:o,nonceAuthorityAddress:s},i=L(e,n.staticAccountKeys);return y(E({version:e.version}),c=>T(r.toBase58(),c),c=>B(a,c),c=>t.slice(1).reduce((u,p)=>w(p,u),c),c=>e.signatures.length?{...c,signatures:i}:c)}
|
|
6
6
|
|
|
7
|
-
exports.
|
|
7
|
+
exports.fromLegacyKeypair = Y;
|
|
8
|
+
exports.fromLegacyPublicKey = $;
|
|
9
|
+
exports.fromVersionedTransactionWithBlockhash = me;
|
|
10
|
+
exports.fromVersionedTransactionWithDurableNonce = he;
|
|
8
11
|
|
|
9
12
|
return exports;
|
|
10
13
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Address } from '@solana/addresses';
|
|
2
|
+
import { PublicKey } from '@solana/web3.js';
|
|
3
|
+
/**
|
|
4
|
+
* Convert from a Legacy Web3 JS PublicKey to a base58 encoded address
|
|
5
|
+
* @param publicKey The PublicKey to convert
|
|
6
|
+
* @returns An Address
|
|
7
|
+
*/
|
|
8
|
+
export declare function fromLegacyPublicKey<TAddress extends string>(publicKey: PublicKey): Address<TAddress>;
|
|
9
|
+
//# sourceMappingURL=address.d.ts.map
|
package/dist/types/index.d.ts
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Keypair } from '@solana/web3.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert from a Legacy Web3 JS Keypair to a CryptoKeyPair
|
|
4
|
+
* @param keypair The Keypair to convert
|
|
5
|
+
* @returns A CryptoKeyPair
|
|
6
|
+
*/
|
|
7
|
+
export declare function fromLegacyKeypair(keypair: Keypair, extractable?: boolean): Promise<CryptoKeyPair>;
|
|
8
|
+
//# sourceMappingURL=keypair.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type IDurableNonceTransaction, type ITransactionWithBlockhashLifetime, type ITransactionWithFeePayer, type Transaction } from '@solana/transactions';
|
|
2
2
|
import type { VersionedTransaction } from '@solana/web3.js';
|
|
3
3
|
export declare function fromVersionedTransactionWithBlockhash(transaction: VersionedTransaction, lastValidBlockHeight?: bigint): Transaction & ITransactionWithFeePayer & ITransactionWithBlockhashLifetime;
|
|
4
|
+
export declare function fromVersionedTransactionWithDurableNonce(transaction: VersionedTransaction): Transaction & ITransactionWithFeePayer & IDurableNonceTransaction;
|
|
4
5
|
//# sourceMappingURL=transaction.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/compat",
|
|
3
|
-
"version": "2.0.0-experimental.
|
|
3
|
+
"version": "2.0.0-experimental.f7d1af1",
|
|
4
4
|
"description": "Helpers for converting from legacy web3js classes",
|
|
5
5
|
"exports": {
|
|
6
6
|
"browser": {
|
|
@@ -49,34 +49,34 @@
|
|
|
49
49
|
"node": ">=17.4"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@solana/functional": "2.0.0-experimental.
|
|
53
|
-
"@solana/
|
|
54
|
-
"@solana/
|
|
52
|
+
"@solana/functional": "2.0.0-experimental.f7d1af1",
|
|
53
|
+
"@solana/transactions": "2.0.0-experimental.f7d1af1",
|
|
54
|
+
"@solana/instructions": "2.0.0-experimental.f7d1af1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@solana/eslint-config-solana": "^1.0.2",
|
|
58
|
-
"@swc/jest": "^0.2.
|
|
59
|
-
"@types/jest": "^29.5.
|
|
58
|
+
"@swc/jest": "^0.2.29",
|
|
59
|
+
"@types/jest": "^29.5.6",
|
|
60
60
|
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
|
61
61
|
"@typescript-eslint/parser": "^6.3.0",
|
|
62
62
|
"agadoo": "^3.0.0",
|
|
63
63
|
"eslint": "^8.45.0",
|
|
64
|
-
"eslint-plugin-jest": "^27.2
|
|
64
|
+
"eslint-plugin-jest": "^27.4.2",
|
|
65
65
|
"eslint-plugin-sort-keys-fix": "^1.1.2",
|
|
66
66
|
"jest": "^29.7.0",
|
|
67
|
-
"jest-environment-jsdom": "^29.
|
|
68
|
-
"jest-runner-eslint": "^2.1.
|
|
67
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
68
|
+
"jest-runner-eslint": "^2.1.2",
|
|
69
69
|
"jest-runner-prettier": "^1.0.0",
|
|
70
70
|
"prettier": "^2.8",
|
|
71
71
|
"tsup": "7.2.0",
|
|
72
72
|
"typescript": "^5.2.2",
|
|
73
73
|
"version-from-git": "^1.1.1",
|
|
74
|
-
"@solana/addresses": "2.0.0-experimental.
|
|
75
|
-
"@solana/keys": "2.0.0-experimental.
|
|
74
|
+
"@solana/addresses": "2.0.0-experimental.f7d1af1",
|
|
75
|
+
"@solana/keys": "2.0.0-experimental.f7d1af1",
|
|
76
|
+
"@solana/web3.js": "0.0.0-development",
|
|
76
77
|
"build-scripts": "0.0.0",
|
|
77
78
|
"test-config": "0.0.0",
|
|
78
|
-
"tsconfig": "0.0.0"
|
|
79
|
-
"@solana/web3.js": "0.0.0-development"
|
|
79
|
+
"tsconfig": "0.0.0"
|
|
80
80
|
},
|
|
81
81
|
"bundlewatch": {
|
|
82
82
|
"defaultCompression": "gzip",
|