@thalalabs/surf 0.0.5 → 0.0.7

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +4 -6
  3. package/build/cjs/abi/aptos_coin.js +158 -0
  4. package/build/cjs/abi/aptos_coin.js.map +1 -0
  5. package/build/cjs/abi/coin.js +783 -0
  6. package/build/cjs/abi/coin.js.map +1 -0
  7. package/build/cjs/abi/event.js +138 -0
  8. package/build/cjs/abi/event.js.map +1 -0
  9. package/build/cjs/abi/fixed_point64.js +380 -0
  10. package/build/cjs/abi/fixed_point64.js.map +1 -0
  11. package/build/cjs/abi/guid.js +158 -0
  12. package/build/cjs/abi/guid.js.map +1 -0
  13. package/build/cjs/abi/table.js +299 -0
  14. package/build/cjs/abi/table.js.map +1 -0
  15. package/build/cjs/core/Client.js +12 -1
  16. package/build/cjs/core/Client.js.map +1 -1
  17. package/build/cjs/core/createEntryPayload.js.map +1 -1
  18. package/build/cjs/core/createViewPayload.js.map +1 -1
  19. package/build/cjs/hooks/useSubmitTransaction.js.map +1 -1
  20. package/build/cjs/types/globalABI.js +3 -0
  21. package/build/cjs/types/globalABI.js.map +1 -0
  22. package/build/cjs/types/struct.js +3 -0
  23. package/build/cjs/types/struct.js.map +1 -0
  24. package/build/esm/abi/aptos_coin.js +155 -0
  25. package/build/esm/abi/aptos_coin.js.map +1 -0
  26. package/build/esm/abi/coin.js +780 -0
  27. package/build/esm/abi/coin.js.map +1 -0
  28. package/build/esm/abi/event.js +135 -0
  29. package/build/esm/abi/event.js.map +1 -0
  30. package/build/esm/abi/fixed_point64.js +377 -0
  31. package/build/esm/abi/fixed_point64.js.map +1 -0
  32. package/build/esm/abi/guid.js +155 -0
  33. package/build/esm/abi/guid.js.map +1 -0
  34. package/build/esm/abi/table.js +296 -0
  35. package/build/esm/abi/table.js.map +1 -0
  36. package/build/esm/core/Client.js +12 -1
  37. package/build/esm/core/Client.js.map +1 -1
  38. package/build/esm/core/createEntryPayload.js.map +1 -1
  39. package/build/esm/core/createViewPayload.js.map +1 -1
  40. package/build/esm/hooks/useSubmitTransaction.js.map +1 -1
  41. package/build/esm/types/globalABI.js +2 -0
  42. package/build/esm/types/globalABI.js.map +1 -0
  43. package/build/esm/types/struct.js +2 -0
  44. package/build/esm/types/struct.js.map +1 -0
  45. package/build/types/abi/aptos_coin.d.ts +100 -0
  46. package/build/types/abi/aptos_coin.d.ts.map +1 -0
  47. package/build/types/abi/coin.d.ts +476 -0
  48. package/build/types/abi/coin.d.ts.map +1 -0
  49. package/build/types/abi/event.d.ts +72 -0
  50. package/build/types/abi/event.d.ts.map +1 -0
  51. package/build/types/abi/fixed_point64.d.ts +225 -0
  52. package/build/types/abi/fixed_point64.d.ts.map +1 -0
  53. package/build/types/abi/guid.d.ts +93 -0
  54. package/build/types/abi/guid.d.ts.map +1 -0
  55. package/build/types/abi/table.d.ts +152 -0
  56. package/build/types/abi/table.d.ts.map +1 -0
  57. package/build/types/core/Client.d.ts +2 -0
  58. package/build/types/core/Client.d.ts.map +1 -1
  59. package/build/types/hooks/useSubmitTransaction.d.ts.map +1 -1
  60. package/build/types/types/abiClient.d.ts +10 -0
  61. package/build/types/types/abiClient.d.ts.map +1 -1
  62. package/build/types/types/common.d.ts.map +1 -1
  63. package/build/types/types/globalABI.d.ts +13 -0
  64. package/build/types/types/globalABI.d.ts.map +1 -0
  65. package/build/types/types/struct.d.ts +25 -0
  66. package/build/types/types/struct.d.ts.map +1 -0
  67. package/package.json +1 -1
  68. package/src/abi/aptos_coin.ts +154 -0
  69. package/src/abi/coin.ts +779 -0
  70. package/src/abi/event.ts +134 -0
  71. package/src/abi/fixed_point64.ts +376 -0
  72. package/src/abi/guid.ts +154 -0
  73. package/src/abi/table.ts +295 -0
  74. package/src/core/Client.ts +19 -2
  75. package/src/core/__tests__/accountResource.test.ts +39 -0
  76. package/src/core/__tests__/createEntryPayload.test.ts +1 -1
  77. package/src/core/__tests__/view.test.ts +1 -1
  78. package/src/core/__tests__/view_vector.test.ts +1 -1
  79. package/src/core/createEntryPayload.ts +0 -2
  80. package/src/core/createViewPayload.ts +4 -7
  81. package/src/hooks/useSubmitTransaction.ts +1 -0
  82. package/src/types/abiClient.ts +12 -1
  83. package/src/types/common.ts +2 -1
  84. package/src/types/globalABI.ts +13 -0
  85. package/src/types/struct.ts +78 -0
@@ -0,0 +1,295 @@
1
+ export const TABLE_ABI = {
2
+ "address": "0x1",
3
+ "name": "table",
4
+ "friends": [
5
+ "0x1::table_with_length"
6
+ ],
7
+ "exposed_functions": [
8
+ {
9
+ "name": "add",
10
+ "visibility": "public",
11
+ "is_entry": false,
12
+ "is_view": false,
13
+ "generic_type_params": [
14
+ {
15
+ "constraints": [
16
+ "copy",
17
+ "drop"
18
+ ]
19
+ },
20
+ {
21
+ "constraints": []
22
+ }
23
+ ],
24
+ "params": [
25
+ "&mut 0x1::table::Table<T0, T1>",
26
+ "T0",
27
+ "T1"
28
+ ],
29
+ "return": []
30
+ },
31
+ {
32
+ "name": "borrow",
33
+ "visibility": "public",
34
+ "is_entry": false,
35
+ "is_view": false,
36
+ "generic_type_params": [
37
+ {
38
+ "constraints": [
39
+ "copy",
40
+ "drop"
41
+ ]
42
+ },
43
+ {
44
+ "constraints": []
45
+ }
46
+ ],
47
+ "params": [
48
+ "&0x1::table::Table<T0, T1>",
49
+ "T0"
50
+ ],
51
+ "return": [
52
+ "&T1"
53
+ ]
54
+ },
55
+ {
56
+ "name": "borrow_mut",
57
+ "visibility": "public",
58
+ "is_entry": false,
59
+ "is_view": false,
60
+ "generic_type_params": [
61
+ {
62
+ "constraints": [
63
+ "copy",
64
+ "drop"
65
+ ]
66
+ },
67
+ {
68
+ "constraints": []
69
+ }
70
+ ],
71
+ "params": [
72
+ "&mut 0x1::table::Table<T0, T1>",
73
+ "T0"
74
+ ],
75
+ "return": [
76
+ "&mut T1"
77
+ ]
78
+ },
79
+ {
80
+ "name": "borrow_mut_with_default",
81
+ "visibility": "public",
82
+ "is_entry": false,
83
+ "is_view": false,
84
+ "generic_type_params": [
85
+ {
86
+ "constraints": [
87
+ "copy",
88
+ "drop"
89
+ ]
90
+ },
91
+ {
92
+ "constraints": [
93
+ "drop"
94
+ ]
95
+ }
96
+ ],
97
+ "params": [
98
+ "&mut 0x1::table::Table<T0, T1>",
99
+ "T0",
100
+ "T1"
101
+ ],
102
+ "return": [
103
+ "&mut T1"
104
+ ]
105
+ },
106
+ {
107
+ "name": "borrow_with_default",
108
+ "visibility": "public",
109
+ "is_entry": false,
110
+ "is_view": false,
111
+ "generic_type_params": [
112
+ {
113
+ "constraints": [
114
+ "copy",
115
+ "drop"
116
+ ]
117
+ },
118
+ {
119
+ "constraints": []
120
+ }
121
+ ],
122
+ "params": [
123
+ "&0x1::table::Table<T0, T1>",
124
+ "T0",
125
+ "&T1"
126
+ ],
127
+ "return": [
128
+ "&T1"
129
+ ]
130
+ },
131
+ {
132
+ "name": "contains",
133
+ "visibility": "public",
134
+ "is_entry": false,
135
+ "is_view": false,
136
+ "generic_type_params": [
137
+ {
138
+ "constraints": [
139
+ "copy",
140
+ "drop"
141
+ ]
142
+ },
143
+ {
144
+ "constraints": []
145
+ }
146
+ ],
147
+ "params": [
148
+ "&0x1::table::Table<T0, T1>",
149
+ "T0"
150
+ ],
151
+ "return": [
152
+ "bool"
153
+ ]
154
+ },
155
+ {
156
+ "name": "destroy",
157
+ "visibility": "friend",
158
+ "is_entry": false,
159
+ "is_view": false,
160
+ "generic_type_params": [
161
+ {
162
+ "constraints": [
163
+ "copy",
164
+ "drop"
165
+ ]
166
+ },
167
+ {
168
+ "constraints": []
169
+ }
170
+ ],
171
+ "params": [
172
+ "0x1::table::Table<T0, T1>"
173
+ ],
174
+ "return": []
175
+ },
176
+ {
177
+ "name": "new",
178
+ "visibility": "public",
179
+ "is_entry": false,
180
+ "is_view": false,
181
+ "generic_type_params": [
182
+ {
183
+ "constraints": [
184
+ "copy",
185
+ "drop"
186
+ ]
187
+ },
188
+ {
189
+ "constraints": [
190
+ "store"
191
+ ]
192
+ }
193
+ ],
194
+ "params": [],
195
+ "return": [
196
+ "0x1::table::Table<T0, T1>"
197
+ ]
198
+ },
199
+ {
200
+ "name": "remove",
201
+ "visibility": "public",
202
+ "is_entry": false,
203
+ "is_view": false,
204
+ "generic_type_params": [
205
+ {
206
+ "constraints": [
207
+ "copy",
208
+ "drop"
209
+ ]
210
+ },
211
+ {
212
+ "constraints": []
213
+ }
214
+ ],
215
+ "params": [
216
+ "&mut 0x1::table::Table<T0, T1>",
217
+ "T0"
218
+ ],
219
+ "return": [
220
+ "T1"
221
+ ]
222
+ },
223
+ {
224
+ "name": "upsert",
225
+ "visibility": "public",
226
+ "is_entry": false,
227
+ "is_view": false,
228
+ "generic_type_params": [
229
+ {
230
+ "constraints": [
231
+ "copy",
232
+ "drop"
233
+ ]
234
+ },
235
+ {
236
+ "constraints": [
237
+ "drop"
238
+ ]
239
+ }
240
+ ],
241
+ "params": [
242
+ "&mut 0x1::table::Table<T0, T1>",
243
+ "T0",
244
+ "T1"
245
+ ],
246
+ "return": []
247
+ }
248
+ ],
249
+ "structs": [
250
+ {
251
+ "name": "Box",
252
+ "is_native": false,
253
+ "abilities": [
254
+ "drop",
255
+ "store",
256
+ "key"
257
+ ],
258
+ "generic_type_params": [
259
+ {
260
+ "constraints": []
261
+ }
262
+ ],
263
+ "fields": [
264
+ {
265
+ "name": "val",
266
+ "type": "T0"
267
+ }
268
+ ]
269
+ },
270
+ {
271
+ "name": "Table",
272
+ "is_native": false,
273
+ "abilities": [
274
+ "store"
275
+ ],
276
+ "generic_type_params": [
277
+ {
278
+ "constraints": [
279
+ "copy",
280
+ "drop"
281
+ ]
282
+ },
283
+ {
284
+ "constraints": []
285
+ }
286
+ ],
287
+ "fields": [
288
+ {
289
+ "name": "handle",
290
+ "type": "address"
291
+ }
292
+ ]
293
+ }
294
+ ]
295
+ } as const;
@@ -3,6 +3,7 @@ import { createViewPayload } from "./createViewPayload.js";
3
3
  import { createEntryPayload } from "./createEntryPayload.js";
4
4
  import type { ABIEntryClient, ABIViewClient, ABIRoot, EntryOptions, EntryPayload, ViewOptions, ViewPayload } from "../types/index.js";
5
5
  import type { TransactionResponse } from "../types/common.js";
6
+ import { ABIResourceClient } from "../types/abiClient.js";
6
7
 
7
8
  export function createClient(options: { nodeUrl: string }): Client {
8
9
  return new Client(
@@ -27,7 +28,7 @@ export class Client {
27
28
  );
28
29
 
29
30
  // Decode the return value
30
- // TODO: for vectors, struct
31
+ // TODO: for struct
31
32
  return result.map((value, i) =>
32
33
  payload.decoders[i] ?
33
34
  payload.decoders[i]!(value) :
@@ -101,7 +102,23 @@ export class Client {
101
102
  this.submitTransaction(payload, { account: args[0].account });
102
103
  };
103
104
  }
104
- })
105
+ }),
106
+ resource: new Proxy({} as ABIResourceClient<T>, {
107
+ get: (_, prop) => {
108
+ let structName = prop.toString();
109
+ return (...args) => {
110
+ if(args[0].type_arguments.length !== 0) {
111
+ structName += `<${args[0].type_arguments.join(",")}>`;
112
+ }
113
+ return this.client.getAccountResource(
114
+ args[0].account,
115
+ `${abi.address}::${abi.name}::${structName}`,
116
+ );
117
+
118
+ // TODO: decode the u64, u128, u256 to bigint
119
+ };
120
+ }
121
+ }),
105
122
  };
106
123
  }
107
124
 
@@ -0,0 +1,39 @@
1
+ /**
2
+ * These test cases depends on network, it call the real contract.
3
+ */
4
+
5
+ import { COIN_ABI } from '../../abi/coin';
6
+ import { createClient } from '../Client';
7
+
8
+ describe('get account resource', () => {
9
+ const client = createClient({
10
+ nodeUrl: 'https://fullnode.testnet.aptoslabs.com/v1',
11
+ });
12
+
13
+ // Act before assertions
14
+ beforeAll(async () => {});
15
+
16
+ // Teardown (cleanup) after assertions
17
+ afterAll(() => {});
18
+
19
+ it('get CoinStore', async () => {
20
+ const result = await client.useABI(COIN_ABI).resource.CoinStore({
21
+ type_arguments: ['0x1::aptos_coin::AptosCoin'],
22
+ account: '0x1',
23
+ });
24
+
25
+ expect(result.data.frozen).toBeFalsy();
26
+ expect(result.data.coin).toBeDefined();
27
+ expect(result.data.deposit_events).toBeDefined();
28
+ expect(result.data.withdraw_events).toBeDefined();
29
+
30
+ // can inference nested struct
31
+ expect(result.data.deposit_events.guid.id.creation_num.startsWith).toBeDefined();
32
+
33
+ // @ts-expect-error field not exist
34
+ expect(result.data.deposit_events.guid.id.abc).toBeUndefined();
35
+
36
+ // @ts-expect-error field not exist
37
+ expect(result.abc).toBeUndefined();
38
+ }, 60000);
39
+ });
@@ -1,7 +1,7 @@
1
1
  import { COIN_ABI } from "../../abi/coin";
2
2
  import { createEntryPayload } from "../createEntryPayload";
3
3
 
4
- // TODO: add struct, vector of vector, vector
4
+ // TODO: add vector of vector, vector
5
5
  describe('createEntryPayload', () => {
6
6
  // Act before assertions
7
7
  beforeAll(async () => { });
@@ -47,7 +47,7 @@ describe('call view functions', () => {
47
47
  `);
48
48
  }, 60000);
49
49
 
50
- it('struct', async () => {
50
+ it('return struct', async () => {
51
51
  const viewPayload = createViewPayload(TIERED_ORACLE_ABI, {
52
52
  function: 'get_last_price',
53
53
  arguments: [],
@@ -5,7 +5,7 @@
5
5
  import { createClient } from '../Client';
6
6
  import { createViewPayload } from '../createViewPayload';
7
7
 
8
- // TODO: add vector<address>, vector<struct>
8
+ // TODO: add vector<address>, vector<vector>
9
9
  describe('call view functions for vector type', () => {
10
10
  const client = createClient({
11
11
  nodeUrl: 'https://fullnode.testnet.aptoslabs.com/v1',
@@ -92,8 +92,6 @@ function argToBCS(type: string, arg: any, serializer: BCS.Serializer) {
92
92
  return;
93
93
  }
94
94
 
95
- // TODO: it's struct
96
-
97
95
  switch (type) { // It's primitive
98
96
  case 'bool':
99
97
  serializer.serializeBool(ensureBoolean(arg));
@@ -34,7 +34,7 @@ export function createViewPayload<
34
34
  else if (type.includes("vector")) {
35
35
  return encodeVector(type, arg as any[]);
36
36
  }
37
- else {
37
+ else { // string or address
38
38
  return arg;
39
39
  }
40
40
  });
@@ -81,8 +81,7 @@ function decodeVector(type: string, value: any[]) {
81
81
  else if (["u64", "u128", "u256"].includes(innerType)) {
82
82
  return value.map((v: string) => BigInt(v));
83
83
  } else {
84
- // 1. TODO: Figure out how to decode Struct type
85
- // 2. TODO: Figure out how to decode Vector of vector, vector of struct
84
+ // TODO: Figure out how to decode Vector of vector
86
85
  return value;
87
86
  }
88
87
  }
@@ -112,10 +111,8 @@ function encodeVector(type: string, value: any[]) {
112
111
  return value;
113
112
  } else if (["u64", "u128", "u256"].includes(innerType)) {
114
113
  return value.map((v: bigint) => v.toString());
115
- } else {
116
- // 1. Address type no need to encode
117
- // 2. TODO: Figure out how to encode Struct type
118
- // 3. TODO: Figure out how to encode Vector of vector, vector of struct
114
+ } else { // string or address
115
+ // TODO: encode for Vector of vector
119
116
  return value;
120
117
  }
121
118
  }
@@ -14,6 +14,7 @@ function isRawPayload(payload: EntryPayload | Types.TransactionPayload_EntryFunc
14
14
  return (<EntryPayload>payload).rawPayload !== undefined;
15
15
  }
16
16
 
17
+ // TODO: add test for this
17
18
  export const useSubmitTransaction = () => {
18
19
  const { signAndSubmitTransaction } = useWallet();
19
20
 
@@ -9,6 +9,7 @@ import type {
9
9
  TransactionResponse,
10
10
  ViewFunctionName
11
11
  } from "./common.js";
12
+ import { ExtractStructGenericParamsType, ExtractStructType, ResourceStructName } from "./struct.js";
12
13
 
13
14
  export type ABIViewClient<T extends ABIRoot> = {
14
15
  [TFuncName in ViewFunctionName<T>]: (payload: {
@@ -24,4 +25,14 @@ export type ABIEntryClient<T extends ABIRoot> = {
24
25
  account: AptosAccount,
25
26
  isSimulation?: boolean
26
27
  }) => Promise<TransactionResponse>
27
- };
28
+ };
29
+
30
+ export type ABIResourceClient<T extends ABIRoot> = {
31
+ [TStructName in ResourceStructName<T>]: (payload: {
32
+ type_arguments: ExtractStructGenericParamsType<T, TStructName>,
33
+ account: `0x${string}`,
34
+ }) => Promise<{
35
+ data: ExtractStructType<T, TStructName>,
36
+ type: string
37
+ }>
38
+ };
@@ -9,7 +9,7 @@ export type Primitive =
9
9
  type Vector = `vector<${Primitive}>`;
10
10
  type VectorOfVector = `vector<vector<${Primitive}>>`;
11
11
 
12
- // TODO: support struct, vector<struct>, and vector<vector<vector>>
12
+ // TODO: support vector<vector<vector>>
13
13
  export type AllTypes = Primitive | Vector | VectorOfVector;
14
14
  type ConvertPrimitiveArgsType<T extends Primitive> =
15
15
  T extends 'bool' ? boolean :
@@ -80,6 +80,7 @@ export type ViewFunctionName<T extends ABIRoot> = MoveViewFunction<T>['name'];
80
80
  export type MoveEntryFunction<T extends ABIRoot> = Extract<Functions<T>[number], { is_entry: true }>;
81
81
  export type EntryFunctionName<T extends ABIRoot> = MoveEntryFunction<T>['name'];
82
82
 
83
+
83
84
  // TODO: Figure out how to return the correct array type
84
85
  type ConvertParams<T extends readonly string[]> = {
85
86
  [P in keyof T]: T[P] extends AllTypes ? ConvertArgsType<T[P]> : Struct<T[P]>;
@@ -0,0 +1,13 @@
1
+ import type { COIN_ABI } from "../abi/coin.js";
2
+ import type { EVENT_ABI } from "../abi/event.js";
3
+ import { FIXED_POINT64_ABI } from "../abi/fixed_point64.js";
4
+ import type { GUID_ABI } from "../abi/guid.js";
5
+ import { TABLE_ABI } from "../abi/table.js";
6
+
7
+ export type GlobalABITable = {
8
+ '0x1::coin': typeof COIN_ABI,
9
+ '0x1::event': typeof EVENT_ABI,
10
+ '0x1::guid': typeof GUID_ABI,
11
+ '0x1::table': typeof TABLE_ABI,
12
+ '0x4dcae85fc5559071906cd5c76b7420fcbb4b0a92f00ab40ffc394aadbbff5ee9::fixed_point64': typeof FIXED_POINT64_ABI,
13
+ };
@@ -0,0 +1,78 @@
1
+ import { ABIRoot } from "./abi.js";
2
+ import { AllTypes, ConvertTypeParams, Primitive } from "./common.js";
3
+ import { GlobalABITable } from "./globalABI.js";
4
+
5
+ type Struct<_T extends string> = object;
6
+
7
+ export type ConvertPrimitiveStructField<T extends Primitive> =
8
+ T extends 'bool' ? boolean :
9
+ T extends 'u8' ? number :
10
+ T extends 'u16' ? number :
11
+ T extends 'u32' ? number :
12
+ T extends 'u64' ? string :
13
+ T extends 'u128' ? string :
14
+ T extends 'u256' ? string :
15
+ T extends 'address' ? `0x${string}` :
16
+ T extends '0x1::string::String' ? string :
17
+ never;
18
+
19
+ type ConvertVectorStructField<TInner> = TInner extends Primitive ? ConvertPrimitiveStructField<TInner>[] :
20
+ (
21
+ TInner extends `vector<${infer TInnerInner}>` ? (
22
+ TInnerInner extends Primitive ? ConvertPrimitiveStructField<TInnerInner>[][] :
23
+ any[][]) : (
24
+ object[]
25
+ )
26
+ );
27
+
28
+ type MoveStruct<T extends ABIRoot> = T['structs'][number];
29
+
30
+ export type ResourceStructName<T extends ABIRoot> = MoveStruct<T>['name'];
31
+
32
+ type ExtractStructFieldsName<
33
+ T extends ABIRoot,
34
+ TStructName extends ResourceStructName<T>> = ExtractStruct<T, TStructName>['fields'][number]['name'];
35
+
36
+ type ExtractStruct<T extends ABIRoot, TResourceName extends ResourceStructName<T>> =
37
+ Extract<MoveStruct<T>, { name: TResourceName }>;
38
+
39
+ type ExtractStructFieldType<
40
+ T extends ABIRoot,
41
+ TStructName extends ResourceStructName<T>,
42
+ TFieldName extends string> = Extract<ExtractStruct<T, TStructName>['fields'][number], { name: TFieldName }>['type'];
43
+
44
+ export type ConvertStructField<T extends AllTypes> =
45
+ T extends Primitive ? ConvertPrimitiveStructField<T> :
46
+ T extends `vector<${infer TInner}>` ? ConvertVectorStructField<TInner> :
47
+ Struct<T>;
48
+
49
+ export type ExtractStructType<
50
+ T extends ABIRoot,
51
+ TStructName extends ResourceStructName<T>> = {
52
+ [TField in ExtractStructFieldsName<T, TStructName>]:
53
+ ExtractStructFieldType<T, TStructName, TField> extends AllTypes ?
54
+ // it's a non-struct type
55
+ ConvertStructField<ExtractStructFieldType<T, TStructName, TField>> :
56
+ // it's a struct type
57
+ ExtractStructTypeGlobal<ExtractStructFieldType<T, TStructName, TField>>;
58
+ };
59
+
60
+ export type ExtractStructRawGenericParamsType<
61
+ T extends ABIRoot,
62
+ TStructName extends ResourceStructName<T>> =
63
+ ExtractStruct<T, TStructName>['generic_type_params'];
64
+
65
+ export type ExtractStructGenericParamsType<
66
+ T extends ABIRoot,
67
+ TStructName extends ResourceStructName<T>> =
68
+ ConvertTypeParams<ExtractStructRawGenericParamsType<T, TStructName>>;
69
+
70
+ type ExtractStructTypeGlobal<TAddress extends string> =
71
+ TAddress extends `${infer TAccountAddress}::${infer TModuleName}::${infer TStructName}${'' | `<${infer _TInnerType}>`}`
72
+ ? `${TAccountAddress}::${TModuleName}` extends keyof GlobalABITable ?
73
+ OmitInner<TStructName> extends ResourceStructName<GlobalABITable[`${TAccountAddress}::${TModuleName}`]> ?
74
+ ExtractStructType<GlobalABITable[`${TAccountAddress}::${TModuleName}`], OmitInner<TStructName>>
75
+ // Unknown struct, use the default struct type
76
+ : Struct<TAddress> : Struct<TAddress> : Struct<TAddress>;
77
+
78
+ type OmitInner<T extends string> = T extends `${infer TOuter}<${infer _TInner}>` ? `${TOuter}` : T;