@magicblock-labs/ephemeral-rollups-sdk 0.3.0 → 0.3.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.
|
@@ -2,226 +2,115 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const magic_router_js_1 = require("../magic-router.js");
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
-
|
|
6
|
-
toBase58: () => address,
|
|
7
|
-
toString: () => address,
|
|
8
|
-
});
|
|
9
|
-
jest.mock("@solana/web3.js", () => {
|
|
10
|
-
const actual = jest.requireActual("@solana/web3.js");
|
|
11
|
-
return {
|
|
12
|
-
...actual,
|
|
13
|
-
Connection: jest.fn().mockImplementation(() => ({
|
|
14
|
-
rpcEndpoint: "http://localhost",
|
|
15
|
-
sendRawTransaction: jest.fn().mockResolvedValue("mock-signature"),
|
|
16
|
-
})),
|
|
17
|
-
Transaction: jest.fn().mockImplementation(() => ({
|
|
18
|
-
feePayer: mockPublicKey("mock-fee-payer"),
|
|
19
|
-
signature: [],
|
|
20
|
-
instructions: [
|
|
21
|
-
{
|
|
22
|
-
keys: [
|
|
23
|
-
{ pubkey: mockPublicKey("key1"), isSigner: true, isWritable: true },
|
|
24
|
-
{
|
|
25
|
-
pubkey: mockPublicKey("key2"),
|
|
26
|
-
isSigner: false,
|
|
27
|
-
isWritable: false,
|
|
28
|
-
},
|
|
29
|
-
],
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
serialize: jest.fn(() => Buffer.from("mock")),
|
|
33
|
-
sign: jest.fn(),
|
|
34
|
-
})),
|
|
35
|
-
Keypair: jest.fn().mockImplementation(() => ({
|
|
36
|
-
publicKey: mockPublicKey("mock-public-key"),
|
|
37
|
-
sign: jest.fn(),
|
|
38
|
-
})),
|
|
39
|
-
PublicKey: jest
|
|
40
|
-
.fn()
|
|
41
|
-
.mockImplementation((address) => mockPublicKey(address)),
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
global.fetch = jest.fn(async () => Promise.resolve({
|
|
45
|
-
json: async () => Promise.resolve({ result: { blockhash: "mock-blockhash" } }),
|
|
46
|
-
}));
|
|
47
|
-
describe("prepareRouterTransaction", () => {
|
|
48
|
-
it("sets recentBlockhash and returns the transaction", async () => {
|
|
49
|
-
const connection = new web3_js_1.Connection("http://localhost");
|
|
50
|
-
const transaction = new web3_js_1.Transaction();
|
|
51
|
-
const result = await (0, magic_router_js_1.prepareMagicTransaction)(connection, transaction);
|
|
52
|
-
expect(result.recentBlockhash).toBe("mock-blockhash");
|
|
53
|
-
expect(global.fetch).toHaveBeenCalledWith("http://localhost", {
|
|
54
|
-
method: "POST",
|
|
55
|
-
headers: { "Content-Type": "application/json" },
|
|
56
|
-
body: JSON.stringify({
|
|
57
|
-
jsonrpc: "2.0",
|
|
58
|
-
id: 1,
|
|
59
|
-
method: "getBlockhashForAccounts",
|
|
60
|
-
params: [["mock-fee-payer", "key1"]],
|
|
61
|
-
}),
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
describe("sendRouterTransaction", () => {
|
|
66
|
-
it("sets recentBlockhash, feePayer, signs, and sends the transaction", async () => {
|
|
67
|
-
const connection = new web3_js_1.Connection("http://localhost");
|
|
68
|
-
const transaction = new web3_js_1.Transaction();
|
|
69
|
-
const signers = [new web3_js_1.Keypair()];
|
|
70
|
-
const signature = await (0, magic_router_js_1.sendMagicTransaction)(connection, transaction, signers);
|
|
71
|
-
expect(transaction.recentBlockhash).toBe("mock-blockhash");
|
|
72
|
-
expect(transaction.feePayer?.toBase58()).toBe("mock-fee-payer");
|
|
73
|
-
expect(transaction.sign).toHaveBeenCalledWith(...signers);
|
|
74
|
-
expect(signature).toBe("mock-signature");
|
|
75
|
-
expect(global.fetch).toHaveBeenCalledWith("http://localhost", {
|
|
76
|
-
method: "POST",
|
|
77
|
-
headers: { "Content-Type": "application/json" },
|
|
78
|
-
body: JSON.stringify({
|
|
79
|
-
jsonrpc: "2.0",
|
|
80
|
-
id: 1,
|
|
81
|
-
method: "getBlockhashForAccounts",
|
|
82
|
-
params: [["mock-fee-payer", "key1"]],
|
|
83
|
-
}),
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
});
|
|
5
|
+
global.fetch = jest.fn();
|
|
87
6
|
describe("getWritableAccounts", () => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
instructions: [
|
|
92
|
-
{
|
|
93
|
-
keys: [
|
|
94
|
-
{ pubkey: mockPublicKey("key1"), isWritable: true },
|
|
95
|
-
{ pubkey: mockPublicKey("key2"), isWritable: false },
|
|
96
|
-
{ pubkey: mockPublicKey("key3"), isWritable: true },
|
|
97
|
-
],
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
};
|
|
101
|
-
const result = (0, magic_router_js_1.getWritableAccounts)(transaction);
|
|
102
|
-
expect(result).toEqual(["fee-payer", "key1", "key3"]);
|
|
103
|
-
});
|
|
104
|
-
it("handles transaction without feePayer", () => {
|
|
105
|
-
const transaction = {
|
|
106
|
-
feePayer: null,
|
|
107
|
-
instructions: [
|
|
108
|
-
{
|
|
109
|
-
keys: [
|
|
110
|
-
{ pubkey: mockPublicKey("key1"), isWritable: true },
|
|
111
|
-
{ pubkey: mockPublicKey("key2"), isWritable: false },
|
|
112
|
-
],
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
};
|
|
116
|
-
const result = (0, magic_router_js_1.getWritableAccounts)(transaction);
|
|
117
|
-
expect(result).toEqual(["key1"]);
|
|
118
|
-
});
|
|
119
|
-
it("handles transaction without instructions", () => {
|
|
120
|
-
const transaction = {
|
|
121
|
-
feePayer: mockPublicKey("fee-payer"),
|
|
122
|
-
instructions: [],
|
|
123
|
-
};
|
|
124
|
-
const result = (0, magic_router_js_1.getWritableAccounts)(transaction);
|
|
125
|
-
expect(result).toEqual(["fee-payer"]);
|
|
7
|
+
const mockPublicKey = (address) => ({
|
|
8
|
+
toBase58: () => address,
|
|
9
|
+
toString: () => address,
|
|
126
10
|
});
|
|
127
11
|
it("deduplicates writable accounts", () => {
|
|
128
|
-
const
|
|
12
|
+
const tx = {
|
|
129
13
|
feePayer: mockPublicKey("fee-payer"),
|
|
130
14
|
instructions: [
|
|
131
15
|
{
|
|
132
16
|
keys: [
|
|
133
|
-
{ pubkey: mockPublicKey("
|
|
134
|
-
{ pubkey: mockPublicKey("
|
|
135
|
-
{ pubkey: mockPublicKey("key2"), isWritable: false },
|
|
17
|
+
{ pubkey: mockPublicKey("k1"), isWritable: true },
|
|
18
|
+
{ pubkey: mockPublicKey("k1"), isWritable: true },
|
|
136
19
|
],
|
|
137
20
|
},
|
|
138
21
|
],
|
|
139
22
|
};
|
|
140
|
-
const result = (0, magic_router_js_1.getWritableAccounts)(
|
|
141
|
-
expect(result).toEqual(["fee-payer", "
|
|
23
|
+
const result = (0, magic_router_js_1.getWritableAccounts)(tx);
|
|
24
|
+
expect(result).toEqual(["fee-payer", "k1"]);
|
|
142
25
|
});
|
|
143
26
|
});
|
|
144
|
-
describe("
|
|
27
|
+
describe("Connection prototype methods", () => {
|
|
28
|
+
let connection;
|
|
29
|
+
let tx;
|
|
145
30
|
beforeEach(() => {
|
|
146
|
-
|
|
31
|
+
connection = new magic_router_js_1.Connection("http://localhost");
|
|
32
|
+
tx = new web3_js_1.Transaction();
|
|
33
|
+
tx.serialize = jest.fn(() => Buffer.from("mock"));
|
|
34
|
+
tx.sign = jest.fn();
|
|
35
|
+
global.fetch.mockReset();
|
|
147
36
|
});
|
|
148
|
-
it("
|
|
149
|
-
const mockIdentityData = {
|
|
150
|
-
result: {
|
|
151
|
-
identity: "mock-validator-identity",
|
|
152
|
-
},
|
|
153
|
-
};
|
|
37
|
+
it("getClosestValidator returns identity", async () => {
|
|
154
38
|
global.fetch.mockResolvedValueOnce({
|
|
155
|
-
json: async () =>
|
|
39
|
+
json: async () => ({ result: { identity: "validator-1" } }),
|
|
156
40
|
});
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
expect(global.fetch).toHaveBeenCalledWith("http://localhost", {
|
|
160
|
-
method: "POST",
|
|
161
|
-
headers: { "Content-Type": "application/json" },
|
|
162
|
-
body: JSON.stringify({
|
|
163
|
-
jsonrpc: "2.0",
|
|
164
|
-
id: 1,
|
|
165
|
-
method: "getIdentity",
|
|
166
|
-
params: [],
|
|
167
|
-
}),
|
|
168
|
-
});
|
|
169
|
-
expect(result.toBase58()).toBe("mock-validator-identity");
|
|
170
|
-
});
|
|
171
|
-
it("handles fetch errors gracefully", async () => {
|
|
172
|
-
global.fetch.mockRejectedValueOnce(new Error("Network error"));
|
|
173
|
-
const connection = new web3_js_1.Connection("http://localhost");
|
|
174
|
-
await expect((0, magic_router_js_1.getClosestValidator)(connection)).rejects.toThrow("Network error");
|
|
41
|
+
const result = await connection.getClosestValidator();
|
|
42
|
+
expect(result).toEqual({ identity: "validator-1" });
|
|
175
43
|
});
|
|
176
|
-
it("
|
|
44
|
+
it("getDelegationStatus works with string account", async () => {
|
|
177
45
|
global.fetch.mockResolvedValueOnce({
|
|
178
|
-
json: async () =>
|
|
46
|
+
json: async () => ({ result: { isDelegated: true } }),
|
|
179
47
|
});
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
describe("getDelegationStatus", () => {
|
|
185
|
-
beforeEach(() => {
|
|
186
|
-
jest.clearAllMocks();
|
|
48
|
+
const result = await connection.getDelegationStatus("account1");
|
|
49
|
+
expect(result).toEqual({ isDelegated: true });
|
|
187
50
|
});
|
|
188
|
-
it("
|
|
51
|
+
it("getDelegationStatus works with PublicKey account", async () => {
|
|
189
52
|
global.fetch.mockResolvedValueOnce({
|
|
190
|
-
json: async () =>
|
|
191
|
-
});
|
|
192
|
-
const connection = new web3_js_1.Connection("http://localhost");
|
|
193
|
-
const account = "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU";
|
|
194
|
-
const result = await (0, magic_router_js_1.getDelegationStatus)(connection, account);
|
|
195
|
-
expect(global.fetch).toHaveBeenCalledWith("http://localhost/getDelegationStatus", {
|
|
196
|
-
method: "POST",
|
|
197
|
-
headers: { "Content-Type": "application/json" },
|
|
198
|
-
body: JSON.stringify({
|
|
199
|
-
jsonrpc: "2.0",
|
|
200
|
-
id: 1,
|
|
201
|
-
method: "getDelegationStatus",
|
|
202
|
-
params: [account],
|
|
203
|
-
}),
|
|
53
|
+
json: async () => ({ result: { isDelegated: false } }),
|
|
204
54
|
});
|
|
55
|
+
const pk = new web3_js_1.PublicKey("11111111111111111111111111111111");
|
|
56
|
+
const result = await connection.getDelegationStatus(pk);
|
|
205
57
|
expect(result).toEqual({ isDelegated: false });
|
|
206
58
|
});
|
|
207
|
-
it("returns
|
|
59
|
+
it("getLatestBlockhashForTransaction returns blockhash", async () => {
|
|
208
60
|
global.fetch.mockResolvedValueOnce({
|
|
209
|
-
json: async () =>
|
|
210
|
-
|
|
211
|
-
const connection = new web3_js_1.Connection("http://localhost");
|
|
212
|
-
const accountKey = new web3_js_1.PublicKey("mock-public-key");
|
|
213
|
-
const result = await (0, magic_router_js_1.getDelegationStatus)(connection, accountKey);
|
|
214
|
-
expect(global.fetch).toHaveBeenCalledWith("http://localhost/getDelegationStatus", {
|
|
215
|
-
method: "POST",
|
|
216
|
-
headers: { "Content-Type": "application/json" },
|
|
217
|
-
body: JSON.stringify({
|
|
218
|
-
jsonrpc: "2.0",
|
|
219
|
-
id: 1,
|
|
220
|
-
method: "getDelegationStatus",
|
|
221
|
-
params: [accountKey.toBase58()],
|
|
61
|
+
json: async () => ({
|
|
62
|
+
result: { blockhash: "mock-blockhash", lastValidBlockHeight: 100 },
|
|
222
63
|
}),
|
|
223
64
|
});
|
|
224
|
-
|
|
65
|
+
const result = await connection.getLatestBlockhashForTransaction(tx);
|
|
66
|
+
expect(result).toEqual({
|
|
67
|
+
blockhash: "mock-blockhash",
|
|
68
|
+
lastValidBlockHeight: 100,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
it("prepareTransaction sets recentBlockhash", async () => {
|
|
72
|
+
jest
|
|
73
|
+
.spyOn(magic_router_js_1.Connection.prototype, "getLatestBlockhashForTransaction")
|
|
74
|
+
.mockResolvedValue({ blockhash: "hb", lastValidBlockHeight: 100 });
|
|
75
|
+
const result = await connection.prepareTransaction(tx);
|
|
76
|
+
expect(result.recentBlockhash).toBe("hb");
|
|
77
|
+
});
|
|
78
|
+
it("sendTransaction signs and sends transaction", async () => {
|
|
79
|
+
jest
|
|
80
|
+
.spyOn(magic_router_js_1.Connection.prototype, "getLatestBlockhashForTransaction")
|
|
81
|
+
.mockResolvedValue({ blockhash: "hb", lastValidBlockHeight: 100 });
|
|
82
|
+
jest
|
|
83
|
+
.spyOn(magic_router_js_1.Connection.prototype, "sendRawTransaction")
|
|
84
|
+
.mockResolvedValue("sig123");
|
|
85
|
+
const signers = [new web3_js_1.Keypair()];
|
|
86
|
+
const sendTx = connection.sendTransaction.bind(connection);
|
|
87
|
+
const signature = await sendTx(tx, signers);
|
|
88
|
+
const signFn = tx.sign.bind(tx);
|
|
89
|
+
const serializeFn = tx.serialize.bind(tx);
|
|
90
|
+
expect(signFn(...signers)).toBeUndefined();
|
|
91
|
+
expect(serializeFn()).toBeInstanceOf(Buffer);
|
|
92
|
+
expect(signature).toBe("sig123");
|
|
93
|
+
});
|
|
94
|
+
it("sendAndConfirmTransaction calls sendTransaction and returns signature", async () => {
|
|
95
|
+
jest
|
|
96
|
+
.spyOn(magic_router_js_1.Connection.prototype, "sendTransaction")
|
|
97
|
+
.mockResolvedValue("sig123");
|
|
98
|
+
jest
|
|
99
|
+
.spyOn(magic_router_js_1.Connection.prototype, "confirmTransaction")
|
|
100
|
+
.mockResolvedValue({ value: { err: null } });
|
|
101
|
+
const signature = await connection.sendAndConfirmTransaction(tx, [
|
|
102
|
+
new web3_js_1.Keypair(),
|
|
103
|
+
]);
|
|
104
|
+
expect(signature).toBe("sig123");
|
|
105
|
+
});
|
|
106
|
+
it("sendAndConfirmTransaction throws SendTransactionError if status has err", async () => {
|
|
107
|
+
jest
|
|
108
|
+
.spyOn(magic_router_js_1.Connection.prototype, "sendTransaction")
|
|
109
|
+
.mockResolvedValue("sig123");
|
|
110
|
+
jest
|
|
111
|
+
.spyOn(magic_router_js_1.Connection.prototype, "confirmTransaction")
|
|
112
|
+
.mockResolvedValue({ value: { err: { some: "error" } } });
|
|
113
|
+
await expect(connection.sendAndConfirmTransaction(tx, [new web3_js_1.Keypair()])).rejects.toThrow(web3_js_1.SendTransactionError);
|
|
225
114
|
});
|
|
226
115
|
});
|
|
227
116
|
//# sourceMappingURL=magic-router.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magic-router.test.js","sourceRoot":"","sources":["../../src/__tests__/magic-router.test.ts"],"names":[],"mappings":";;AAAA,
|
|
1
|
+
{"version":3,"file":"magic-router.test.js","sourceRoot":"","sources":["../../src/__tests__/magic-router.test.ts"],"names":[],"mappings":"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"}
|
package/lib/magic-router.d.ts
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
import { Connection, Transaction
|
|
1
|
+
import { Connection, Transaction } from "@solana/web3.js";
|
|
2
2
|
export declare function getWritableAccounts(transaction: Transaction): string[];
|
|
3
|
-
export
|
|
4
|
-
export declare function getDelegationStatus(connection: Connection, account: PublicKey | string): Promise<{
|
|
5
|
-
isDelegated: boolean;
|
|
6
|
-
}>;
|
|
7
|
-
export declare function getLatestBlockhashForMagicTransaction(connection: Connection, transaction: Transaction, options?: ConfirmOptions): Promise<BlockhashWithExpiryBlockHeight>;
|
|
8
|
-
export declare function prepareMagicTransaction(connection: Connection, transaction: Transaction, options?: ConfirmOptions): Promise<Transaction>;
|
|
9
|
-
export declare function sendMagicTransaction(connection: Connection, transaction: Transaction, signersOrOptions?: Signer[] | SendOptions, options?: SendOptions): Promise<TransactionSignature>;
|
|
10
|
-
export declare function confirmMagicTransaction(connection: Connection, strategy: TransactionConfirmationStrategy | string, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
|
|
11
|
-
export declare function sendAndConfirmMagicTransaction(connection: Connection, transaction: Transaction, signers: Signer[], options?: ConfirmOptions & Readonly<{
|
|
12
|
-
abortSignal?: AbortSignal;
|
|
13
|
-
}>): Promise<TransactionSignature>;
|
|
14
|
-
export declare function pollSignatureStatus(getSignatureStatus: (connection: Connection, signature: TransactionSignature, config?: SignatureStatusConfig) => Promise<RpcResponseAndContext<SignatureStatus | null>>, connection: Connection, signature: string, { intervalMs, timeoutMs, commitment, abortSignal, }?: {
|
|
15
|
-
intervalMs?: number;
|
|
16
|
-
timeoutMs?: number;
|
|
17
|
-
commitment?: Commitment;
|
|
18
|
-
abortSignal?: AbortSignal;
|
|
19
|
-
}): Promise<RpcResponseAndContext<SignatureResult>>;
|
|
3
|
+
export { Connection };
|
|
20
4
|
//# sourceMappingURL=magic-router.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magic-router.d.ts","sourceRoot":"","sources":["../src/magic-router.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,
|
|
1
|
+
{"version":3,"file":"magic-router.d.ts","sourceRoot":"","sources":["../src/magic-router.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EAQZ,MAAM,iBAAiB,CAAC;AAKzB,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,YAgB3D;AA6LD,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
package/lib/magic-router.js
CHANGED
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Connection = void 0;
|
|
6
4
|
exports.getWritableAccounts = getWritableAccounts;
|
|
7
|
-
exports.getClosestValidator = getClosestValidator;
|
|
8
|
-
exports.getDelegationStatus = getDelegationStatus;
|
|
9
|
-
exports.getLatestBlockhashForMagicTransaction = getLatestBlockhashForMagicTransaction;
|
|
10
|
-
exports.prepareMagicTransaction = prepareMagicTransaction;
|
|
11
|
-
exports.sendMagicTransaction = sendMagicTransaction;
|
|
12
|
-
exports.confirmMagicTransaction = confirmMagicTransaction;
|
|
13
|
-
exports.sendAndConfirmMagicTransaction = sendAndConfirmMagicTransaction;
|
|
14
|
-
exports.pollSignatureStatus = pollSignatureStatus;
|
|
15
5
|
const web3_js_1 = require("@solana/web3.js");
|
|
16
|
-
|
|
17
|
-
const bs58_1 = __importDefault(require("bs58"));
|
|
6
|
+
Object.defineProperty(exports, "Connection", { enumerable: true, get: function () { return web3_js_1.Connection; } });
|
|
18
7
|
function getWritableAccounts(transaction) {
|
|
19
8
|
const writableAccounts = new Set();
|
|
20
9
|
if (transaction.feePayer) {
|
|
@@ -29,8 +18,8 @@ function getWritableAccounts(transaction) {
|
|
|
29
18
|
}
|
|
30
19
|
return Array.from(writableAccounts);
|
|
31
20
|
}
|
|
32
|
-
async function
|
|
33
|
-
const response = await fetch(
|
|
21
|
+
web3_js_1.Connection.prototype.getClosestValidator = async function () {
|
|
22
|
+
const response = await fetch(this.rpcEndpoint, {
|
|
34
23
|
method: "POST",
|
|
35
24
|
headers: { "Content-Type": "application/json" },
|
|
36
25
|
body: JSON.stringify({
|
|
@@ -40,20 +29,15 @@ async function getClosestValidator(routerConnection) {
|
|
|
40
29
|
params: [],
|
|
41
30
|
}),
|
|
42
31
|
});
|
|
43
|
-
const identityData = await response.json();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
throw new Error("Invalid identity response");
|
|
32
|
+
const identityData = (await response.json())?.result;
|
|
33
|
+
if (identityData === null || identityData.identity === undefined) {
|
|
34
|
+
throw new Error("Invalid response");
|
|
47
35
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
return validatorKey;
|
|
53
|
-
}
|
|
54
|
-
async function getDelegationStatus(connection, account) {
|
|
36
|
+
return identityData;
|
|
37
|
+
};
|
|
38
|
+
web3_js_1.Connection.prototype.getDelegationStatus = async function (account) {
|
|
55
39
|
const accountAddress = typeof account === "string" ? account : account.toBase58();
|
|
56
|
-
const response = await fetch(`${
|
|
40
|
+
const response = await fetch(`${this.rpcEndpoint}/getDelegationStatus`, {
|
|
57
41
|
method: "POST",
|
|
58
42
|
headers: { "Content-Type": "application/json" },
|
|
59
43
|
body: JSON.stringify({
|
|
@@ -63,188 +47,77 @@ async function getDelegationStatus(connection, account) {
|
|
|
63
47
|
params: [accountAddress],
|
|
64
48
|
}),
|
|
65
49
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
async function
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
async function
|
|
85
|
-
const blockHashData = await
|
|
50
|
+
return (await response.json()).result;
|
|
51
|
+
};
|
|
52
|
+
web3_js_1.Connection.prototype.getLatestBlockhashForTransaction =
|
|
53
|
+
async function (transaction, options) {
|
|
54
|
+
const writableAccounts = getWritableAccounts(transaction);
|
|
55
|
+
const blockHashResponse = await fetch(this.rpcEndpoint, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "Content-Type": "application/json" },
|
|
58
|
+
body: JSON.stringify({
|
|
59
|
+
jsonrpc: "2.0",
|
|
60
|
+
id: 1,
|
|
61
|
+
method: "getBlockhashForAccounts",
|
|
62
|
+
params: [writableAccounts],
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
const blockHashData = await blockHashResponse.json();
|
|
66
|
+
return blockHashData.result;
|
|
67
|
+
};
|
|
68
|
+
web3_js_1.Connection.prototype.prepareTransaction = async function (transaction, options) {
|
|
69
|
+
const blockHashData = await this.getLatestBlockhashForTransaction(transaction, options);
|
|
86
70
|
transaction.recentBlockhash = blockHashData.blockhash;
|
|
87
71
|
return transaction;
|
|
88
|
-
}
|
|
89
|
-
async function
|
|
72
|
+
};
|
|
73
|
+
web3_js_1.Connection.prototype.sendTransaction = async function (transaction, signersOrOptions, options) {
|
|
90
74
|
const sendOpts = Array.isArray(signersOrOptions)
|
|
91
75
|
? (options ?? undefined)
|
|
92
76
|
: (signersOrOptions ?? undefined);
|
|
93
|
-
const latestBlockhash = await
|
|
77
|
+
const latestBlockhash = await this.getLatestBlockhashForTransaction(transaction, sendOpts);
|
|
78
|
+
transaction.recentBlockhash = latestBlockhash.blockhash;
|
|
94
79
|
transaction.lastValidBlockHeight =
|
|
95
80
|
latestBlockhash.lastValidBlockHeight;
|
|
96
|
-
transaction.recentBlockhash = latestBlockhash.blockhash;
|
|
97
81
|
if (Array.isArray(signersOrOptions)) {
|
|
98
|
-
transaction.sign
|
|
82
|
+
transaction.sign(...signersOrOptions);
|
|
99
83
|
}
|
|
100
84
|
const wireTransaction = transaction.serialize();
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
async function
|
|
104
|
-
|
|
105
|
-
if (typeof strategy === "string") {
|
|
106
|
-
rawSignature = strategy;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
const config = strategy;
|
|
110
|
-
if (config.abortSignal != null && config.abortSignal.aborted) {
|
|
111
|
-
return Promise.reject(config.abortSignal.reason ?? new Error("Aborted"));
|
|
112
|
-
}
|
|
113
|
-
rawSignature = config.signature;
|
|
114
|
-
}
|
|
115
|
-
let decodedSignature;
|
|
116
|
-
try {
|
|
117
|
-
decodedSignature = bs58_1.default.decode(rawSignature);
|
|
118
|
-
}
|
|
119
|
-
catch (err) {
|
|
120
|
-
throw new Error("signature must be base58 encoded: " + rawSignature);
|
|
121
|
-
}
|
|
122
|
-
(0, assert_1.default)(decodedSignature.length === 64, "signature has invalid length");
|
|
123
|
-
const status = await pollSignatureStatus(getSignatureStatus, connection, rawSignature, {
|
|
124
|
-
intervalMs: 100,
|
|
125
|
-
timeoutMs: 10000,
|
|
126
|
-
commitment,
|
|
127
|
-
});
|
|
128
|
-
return status;
|
|
129
|
-
}
|
|
130
|
-
async function sendAndConfirmMagicTransaction(connection, transaction, signers, options) {
|
|
131
|
-
const signature = await sendMagicTransaction(connection, transaction, signers, options);
|
|
85
|
+
return this.sendRawTransaction(wireTransaction, sendOpts);
|
|
86
|
+
};
|
|
87
|
+
web3_js_1.Connection.prototype.sendAndConfirmTransaction = async function (transaction, signers, options) {
|
|
88
|
+
const signature = await this.sendTransaction(transaction, signers, options);
|
|
132
89
|
let status;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
status = (await
|
|
90
|
+
const { recentBlockhash, lastValidBlockHeight, minNonceContextSlot, nonceInfo, } = transaction;
|
|
91
|
+
if (recentBlockhash !== undefined && lastValidBlockHeight !== undefined) {
|
|
92
|
+
status = (await this.confirmTransaction({
|
|
136
93
|
abortSignal: options?.abortSignal,
|
|
137
94
|
signature,
|
|
138
|
-
blockhash:
|
|
139
|
-
lastValidBlockHeight
|
|
95
|
+
blockhash: recentBlockhash,
|
|
96
|
+
lastValidBlockHeight,
|
|
140
97
|
}, options?.commitment)).value;
|
|
141
98
|
}
|
|
142
|
-
else if (
|
|
143
|
-
|
|
144
|
-
const { nonceInstruction } = transaction.nonceInfo;
|
|
99
|
+
else if (minNonceContextSlot !== undefined && nonceInfo !== undefined) {
|
|
100
|
+
const { nonceInstruction } = nonceInfo;
|
|
145
101
|
const nonceAccountPubkey = nonceInstruction.keys[0].pubkey;
|
|
146
|
-
status = (await
|
|
102
|
+
status = (await this.confirmTransaction({
|
|
147
103
|
abortSignal: options?.abortSignal,
|
|
148
|
-
minContextSlot:
|
|
104
|
+
minContextSlot: minNonceContextSlot,
|
|
149
105
|
nonceAccountPubkey,
|
|
150
|
-
nonceValue:
|
|
106
|
+
nonceValue: nonceInfo.nonce,
|
|
151
107
|
signature,
|
|
152
108
|
}, options?.commitment)).value;
|
|
153
109
|
}
|
|
154
110
|
else {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
"supplied along with an `abortSignal`. Only transactions having `lastValidBlockHeight` " +
|
|
158
|
-
"or a combination of `nonceInfo` and `minNonceContextSlot` are abortable.");
|
|
159
|
-
}
|
|
160
|
-
status = (await confirmMagicTransaction(connection, signature, options?.commitment)).value;
|
|
111
|
+
status = (await this.confirmTransaction(signature, options?.commitment))
|
|
112
|
+
.value;
|
|
161
113
|
}
|
|
162
114
|
if (status.err != null) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
throw new Error(`Transaction ${signature} failed (${JSON.stringify(status)})`);
|
|
115
|
+
throw new web3_js_1.SendTransactionError({
|
|
116
|
+
action: "send",
|
|
117
|
+
signature,
|
|
118
|
+
transactionMessage: `Status: (${JSON.stringify(status)})`,
|
|
119
|
+
});
|
|
171
120
|
}
|
|
172
121
|
return signature;
|
|
173
|
-
}
|
|
174
|
-
async function getSignatureStatus(connection, signature, config) {
|
|
175
|
-
const { context, value: values } = await getSignatureStatuses(connection, [signature], config);
|
|
176
|
-
if (values.length === 0) {
|
|
177
|
-
const value = null;
|
|
178
|
-
return {
|
|
179
|
-
context,
|
|
180
|
-
value,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
(0, assert_1.default)(values.length === 1);
|
|
185
|
-
const value = values[0];
|
|
186
|
-
return {
|
|
187
|
-
context,
|
|
188
|
-
value,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
async function getSignatureStatuses(connection, signatures, config) {
|
|
193
|
-
const params = config ? [signatures, config] : [signatures];
|
|
194
|
-
const unsafeRes = await fetch(connection.rpcEndpoint, {
|
|
195
|
-
method: "POST",
|
|
196
|
-
headers: { "Content-Type": "application/json" },
|
|
197
|
-
body: JSON.stringify({
|
|
198
|
-
jsonrpc: "2.0",
|
|
199
|
-
id: 1,
|
|
200
|
-
method: "getSignatureStatuses",
|
|
201
|
-
params,
|
|
202
|
-
}),
|
|
203
|
-
});
|
|
204
|
-
const res = await unsafeRes.json();
|
|
205
|
-
return res.result;
|
|
206
|
-
}
|
|
207
|
-
async function pollSignatureStatus(getSignatureStatus, connection, signature, { intervalMs = 50, timeoutMs = 12000, commitment = "confirmed", abortSignal, } = {}) {
|
|
208
|
-
const maxTries = Math.ceil(timeoutMs / intervalMs);
|
|
209
|
-
let tries = 0;
|
|
210
|
-
return new Promise((resolve, reject) => {
|
|
211
|
-
const intervalId = setInterval(() => {
|
|
212
|
-
if (abortSignal != null && abortSignal.aborted) {
|
|
213
|
-
clearInterval(intervalId);
|
|
214
|
-
reject(abortSignal.reason ?? new Error("Polling aborted"));
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
tries++;
|
|
218
|
-
void (async () => {
|
|
219
|
-
try {
|
|
220
|
-
const result = await getSignatureStatus(connection, signature);
|
|
221
|
-
if (result.value !== null) {
|
|
222
|
-
if (result.value.confirmationStatus === commitment ||
|
|
223
|
-
result.value.confirmationStatus === "finalized") {
|
|
224
|
-
clearInterval(intervalId);
|
|
225
|
-
resolve({
|
|
226
|
-
context: result.context,
|
|
227
|
-
value: result.value,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
else if (tries >= maxTries) {
|
|
232
|
-
clearInterval(intervalId);
|
|
233
|
-
const timeoutValue = {
|
|
234
|
-
err: new Error("Timeout"),
|
|
235
|
-
};
|
|
236
|
-
resolve({
|
|
237
|
-
context: result.context,
|
|
238
|
-
value: timeoutValue,
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
catch (err) {
|
|
243
|
-
clearInterval(intervalId);
|
|
244
|
-
reject(err);
|
|
245
|
-
}
|
|
246
|
-
})();
|
|
247
|
-
}, intervalMs);
|
|
248
|
-
});
|
|
249
|
-
}
|
|
122
|
+
};
|
|
250
123
|
//# sourceMappingURL=magic-router.js.map
|
package/lib/magic-router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magic-router.js","sourceRoot":"","sources":["../src/magic-router.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"magic-router.js","sourceRoot":"","sources":["../src/magic-router.ts"],"names":[],"mappings":"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"}
|