Giter Site home page Giter Site logo

ic-assets's Introduction

IC-Assets

A motoko library implementation of the Assets Canister with v2 certification. Allows you to serve files from a canister and access it via the <canister-id>.icp0.io domain instead of <canister-id>.raw.ic0.io domain.

Demo: A simple frontend for uploading and serving certified files

The code for the demo is in the example/main.mo file.

Usage

You can either import the library into you canister, deploy it as a standalone canister or deploy it as a subcanister.

Importing the library

    import Assets "mo:ic-assets";

    actor class() = this_canister {
        stable var assets_sstore = Assets.init_stable_store(owner);
        assets_sstore := Assets.migrate(assets_sstore);

        let assets = Assets.Assets(assets_sstore);

        /// Need to call this function the first time the canister is created
        public shared func init() : async () {
            let id = Principal.fromActor(this_canister);
            assets.set_canister_id(id);
            assets.set_streaming_callback(http_request_streaming_callback);
        };
        
        public shared ({ caller }) func store(args : Assets.StoreArgs) : async () {
            assets.store(caller, args);
        };

        ... // other functions from the Assets interface

        public query func http_request_streaming_callback(token_blob : Assets.StreamingToken) : async ?(Assets.StreamingCallbackResponse) {
            ?assets.http_request_streaming_callback(token_blob);
        };

        public query func http_request(request : Assets.HttpRequest) : async Assets.HttpResponse {
            assets.http_request(request);
        };
    }

Deploying as a standalone canister

  • git clone https://github.com/NatLabs/ic-assets
  • mops install
  • dfx start --background
  • dfx deploy assets_canister
  • dfx canister call assets_canister init

Deploying as a subcanister

    import Text "mo:base/Text";
    import Option "mo:base/Option";
    import Cycles "mo:base/ExperimentalCycles";

    import Assets "mo:ic-assets";
    import AssetsCanister "mo:ic-assets/Canister";

    actor {
        stable var opt_assets : ?AssetsCanister.AssetsCanister = null;

        func assets() : AssetsCanister.AssetsCanister {
            let ?a = opt_assets; return a;
        };

        public shared func create_assets() : async () {
            switch(opt_assets) {
                case (?_) { };
                case null {
                    Cycles.add(1_000_000_000_000);
                    opt_assets := ?(await AssetsCanister.AssetsCanister(#Init({})););
                    assets().init();
                };
            };
        };

        public shared func store_text_file(): async (){
            let args = AssetsCanister.StoreArgs {
                key = "/hello.txt";
                content_type = "text/plain";
                key = "/hello";
                content = "Hello, World!";
                sha256 = null;
                content_encoding = "identity";
                is_aliased = ?true;
            };

            await assets().store(args);

            let file = await assets().get({
                key = "/hello.txt";
                accept_encodings = [];
            });
            
            assert result.content == "Hello, World!";
            assert result.content_type == "text/plain";
            assert result.content_encoding == "identity";
            assert result.total_length == 13;
            assert Option.isSome(result.sha256);
        };
        
        /// Redirects all requests with the prefix '/assets/' to the assets canister
        public query func http_request(request : Assets.HttpRequest) : async Assets.HttpResponse {
            if (Text.startWith(request.url.path, "/assets/")) {
                let assets_canister_id = Principal.toText(Principal.fromActor(assets()));

                let path = Text.trimStart(request.url.path, "/assets/");
                let asset_url = assets_canister_id # ".icp0.io/" # path;

                let http_response = {
                    status_code = 307;
                    headers = [("Location", asset_url)];
                    body = "";
                    upgrade = null;
                    streaming_strategy = null;
                };

                return http_response;

                // return await assets().http_request(request); - doesn't work, as CertifiedData.getCertificate() cannot be called in either composite query calls or inter-canister calls
            };

            return {
                status_code = 404;
                headers = [];
                body = "Not found";
                upgrade = null;
                streaming_strategy = null;
            };
        };
    }

ic-assets's People

Contributors

tomijaga avatar

Watchers

 avatar

ic-assets's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.