Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add fetchCandid() function to @dfinity/agent #630

Merged
merged 9 commits into from Sep 29, 2022
10 changes: 8 additions & 2 deletions docs/generated/changelog.html
Expand Up @@ -18,8 +18,14 @@ <h2>Version 0.13.3</h2>
the _key non-nullable. This fixes a regression with async window.open behavior in Safari
</li>
<li>
HttpAgent now offers a method to sync time with the replica, provided a specific canister.
This can be used to set proper Expiry times when a device has fallen out of sync with the replica.
HttpAgent now offers a method to sync time with the replica, provided a specific canister.
This can be used to set proper Expiry times when a device has fallen out of sync with the
replica.
</li>
<li>
Adds a top-level <code>fetchCandid()</code> function which retrieves the Candid interface
for a given canister id.
</li>
</ul>
<h2>Version 0.13.2</h2>
<ul>
Expand Down
27 changes: 27 additions & 0 deletions packages/agent/src/fetch_candid.test.ts
@@ -0,0 +1,27 @@
import { fetchCandid, HttpAgent } from '.';
import { IDL } from '@dfinity/candid';
import * as cbor from './cbor';

test('simulate fetching a Candid interface', async () => {
const mockFetch = jest.fn().mockImplementationOnce((/*resource, init*/) => {
return Promise.resolve(
new Response(
cbor.encode({
status: 'replied',
reply: {
arg: IDL.encode([IDL.Text], ['service {}']),
},
}),
{
status: 200,
},
),
);
});

const agent = new HttpAgent({ fetch: mockFetch, host: 'http://localhost' });

const candid = await fetchCandid(agent, 'ryjl3-tyaaa-aaaaa-aaaba-cai');

expect(candid).toMatch(/service/);
});
21 changes: 21 additions & 0 deletions packages/agent/src/fetch_candid.ts
@@ -0,0 +1,21 @@
import { Actor, ActorSubclass, Agent } from '.';
import { IDL } from '@dfinity/candid';

// Common interface for the hidden `__get_candid_interface_tmp_hack` actor method
const tmpHackInterface: IDL.InterfaceFactory = ({ IDL }) =>
IDL.Service({
__get_candid_interface_tmp_hack: IDL.Func([], [IDL.Text], ['query']),
});

/**
* Retrieves the Candid interface for the specified canister..
*
* @param agent The agent to use for the request (usually an `HttpAgent`)
* @param canisterId A string corresponding to the canister ID
* @returns Candid source code
*/
export async function fetchCandid(agent: Agent, canisterId: string): Promise<string> {
rvanasa marked this conversation as resolved.
Show resolved Hide resolved
const actor: ActorSubclass = Actor.createActor(tmpHackInterface, { agent, canisterId });
const candidSource = (await actor.__get_candid_interface_tmp_hack()) as string;
return candidSource;
}
1 change: 1 addition & 0 deletions packages/agent/src/index.ts
Expand Up @@ -8,6 +8,7 @@ export * from './agent/http/transforms';
export * from './agent/http/types';
export * from './canisters/asset';
export * from './canisters/management';
export * from './fetch_candid';
export * from './request_id';
export * from './utils/bls';
export * from './utils/buffer';
Expand Down
2 changes: 1 addition & 1 deletion packages/candid/tsconfig.json
Expand Up @@ -18,6 +18,6 @@
"strict": true,
"target": "es2017"
},
"include": ["types/*", "src/**/*", "vendor/bls"],
"include": ["types/*", "src/**/*", "vendor/bls", "../agent/src/fetch.ts"],
"references": []
}