-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuseNear.ts
81 lines (73 loc) · 2.12 KB
/
useNear.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import equal from 'lodash.isequal'
import { useEffect, useState } from "react"
import { useParams } from "react-router-dom"
import {
ContractInterface,
init,
getSchema,
getSchemaCached,
SchemaInterface,
} from "../near"
type ContractName = string
const stub = {
contract: undefined,
config: undefined,
near: undefined,
currentUser: Promise.resolve(undefined),
signIn: () => { },
signOut: () => { },
schema: undefined,
changeMethods: [] as string[],
viewMethods: [] as string[],
methods: {},
getMethod: () => undefined,
getDefinition: () => undefined,
canCall: () => Promise.resolve([true, undefined] as const),
} as const
type NearInterface = ContractInterface & SchemaInterface & { stale?: true }
/**
* Get `contract` from url params and use it to initialize near connection.
*
* If no `contract` in url params, returns blanks
*/
export default function useNear(): NearInterface | typeof stub {
const { contract } = useParams<{ contract: ContractName }>()
const [initialSchema] = useState(getSchemaCached(contract))
const [cache, setCache] = useState<Record<ContractName, NearInterface>>(
(!contract || !initialSchema) ? {} : {
[contract]: {
stale: true,
...init(contract),
...initialSchema,
}
}
)
useEffect(() => {
if (!contract || (cache[contract] && !cache[contract].stale)) return
(async () => {
/* First update with schema cached from localStorage while new schema loads from remote endpoint */
const schema = getSchemaCached(contract)
if (schema && (!initialSchema || initialSchema.loadedAt !== schema.loadedAt)) {
setCache({
...cache,
[contract]: {
...init(contract),
...schema,
}
})
}
const freshSchema = await getSchema(contract)
if (!equal(freshSchema.schema, schema?.schema)) {
setCache({
...cache,
[contract]: {
...init(contract),
...freshSchema,
}
})
}
})()
}, [initialSchema, cache, contract])
if (!contract) return stub
return cache[contract] ?? stub
}